Merge branch 'develop'
This commit is contained in:
commit
1ebed26b0d
33 changed files with 429 additions and 377 deletions
14
.travis.yml
14
.travis.yml
|
|
@ -31,7 +31,9 @@ jobs:
|
||||||
script: .travis/script_test.sh
|
script: .travis/script_test.sh
|
||||||
|
|
||||||
- name: "Linux arm64 tests"
|
- name: "Linux arm64 tests"
|
||||||
arch: arm64
|
arch: arm64-graviton2
|
||||||
|
group: edge
|
||||||
|
virt: lxd
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
|
|
@ -54,7 +56,7 @@ jobs:
|
||||||
env:
|
env:
|
||||||
- INSTALL_DIR="sfizz-${TRAVIS_BRANCH}-${TRAVIS_OS_NAME}-${TRAVIS_CPU_ARCH}"
|
- INSTALL_DIR="sfizz-${TRAVIS_BRANCH}-${TRAVIS_OS_NAME}-${TRAVIS_CPU_ARCH}"
|
||||||
script: .travis/script_osx.sh
|
script: .travis/script_osx.sh
|
||||||
after_success: .travis/prepare_osx.sh
|
after_success: .travis/prepare_tarball.sh
|
||||||
|
|
||||||
- name: "MOD devices arm"
|
- name: "MOD devices arm"
|
||||||
env:
|
env:
|
||||||
|
|
@ -100,7 +102,9 @@ jobs:
|
||||||
after_success: .travis/prepare_tarball.sh
|
after_success: .travis/prepare_tarball.sh
|
||||||
|
|
||||||
- name: "Linux arm64 library"
|
- name: "Linux arm64 library"
|
||||||
arch: arm64
|
arch: arm64-graviton2
|
||||||
|
group: edge
|
||||||
|
virt: lxd
|
||||||
env:
|
env:
|
||||||
- INSTALL_DIR="sfizz-${TRAVIS_BRANCH}-${TRAVIS_OS_NAME}-${TRAVIS_CPU_ARCH}"
|
- INSTALL_DIR="sfizz-${TRAVIS_BRANCH}-${TRAVIS_OS_NAME}-${TRAVIS_CPU_ARCH}"
|
||||||
addons:
|
addons:
|
||||||
|
|
@ -113,7 +117,9 @@ jobs:
|
||||||
after_success: .travis/prepare_tarball.sh
|
after_success: .travis/prepare_tarball.sh
|
||||||
|
|
||||||
- name: "Linux arm64 static plugins"
|
- name: "Linux arm64 static plugins"
|
||||||
arch: arm64
|
arch: arm64-graviton2
|
||||||
|
group: edge
|
||||||
|
virt: lxd
|
||||||
env:
|
env:
|
||||||
- INSTALL_DIR="sfizz-plugins-${TRAVIS_BRANCH}-${TRAVIS_OS_NAME}-${TRAVIS_CPU_ARCH}"
|
- INSTALL_DIR="sfizz-plugins-${TRAVIS_BRANCH}-${TRAVIS_OS_NAME}-${TRAVIS_CPU_ARCH}"
|
||||||
- ENABLE_VST_PLUGIN=OFF
|
- ENABLE_VST_PLUGIN=OFF
|
||||||
|
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -ex
|
|
||||||
. .travis/environment.sh
|
|
||||||
|
|
||||||
cmake_dir="cmake-3.13.0-${TRAVIS_OS_NAME}-${TRAVIS_CPU_ARCH}"
|
|
||||||
cmake_arc="${cmake_dir}.tar.gz"
|
|
||||||
cmake_url="https://github.com/sfztools/cmake/releases/download/${TRAVIS_OS_NAME}/${cmake_arc}"
|
|
||||||
|
|
||||||
if [[ ${CROSS_COMPILE} == "mingw32" || ${CROSS_COMPILE} == "mingw64" ]]; then
|
|
||||||
buildenv bash -c "echo Hello from container" # ensure to start the container
|
|
||||||
docker cp "$container":/etc/pacman.conf pacman.conf
|
|
||||||
cat >>pacman.conf <<EOF
|
|
||||||
[multilib]
|
|
||||||
Include = /etc/pacman.d/mirrorlist
|
|
||||||
|
|
||||||
[mingw-w64]
|
|
||||||
SigLevel = Optional TrustAll
|
|
||||||
Server = https://github.com/jpcima/arch-mingw-w64/releases/download/repo.\$arch/
|
|
||||||
EOF
|
|
||||||
docker cp pacman.conf "$container":/etc/pacman.conf
|
|
||||||
rm -f pacman.conf
|
|
||||||
elif [[ ${TRAVIS_OS_NAME} == "linux" ]]; then
|
|
||||||
wget -q ${cmake_url}
|
|
||||||
tar xzf ${cmake_arc}
|
|
||||||
cd ${TRAVIS_BUILD_DIR}/${cmake_dir}
|
|
||||||
sudo cp bin/* /usr/local/bin/
|
|
||||||
sudo cp -r share/* /usr/local/share/
|
|
||||||
elif [[ ${TRAVIS_OS_NAME} == "osx" ]]; then
|
|
||||||
sudo ln -s /usr/local /opt/local
|
|
||||||
brew update
|
|
||||||
brew upgrade cmake
|
|
||||||
brew install jack
|
|
||||||
fi
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -ex
|
|
||||||
|
|
||||||
test -z "$CONTAINER"
|
|
||||||
|
|
||||||
if ! [ -z "$CONTAINER" ]; then
|
|
||||||
. .travis/docker_container.sh
|
|
||||||
else
|
|
||||||
. .travis/no_container.sh
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd build
|
|
||||||
buildenv make DESTDIR=${PWD}/${INSTALL_DIR} install
|
|
||||||
|
|
||||||
# Bundle LV2 dependencies
|
|
||||||
cd "${INSTALL_DIR}"/Library/Audio/Plug-Ins/LV2
|
|
||||||
dylibbundler -od -b -x sfizz.lv2/Contents/Binary/sfizz.so -d sfizz.lv2/Contents/libs/ -p @loader_path/../libs/
|
|
||||||
dylibbundler -od -b -x sfizz.lv2/Contents/Binary/sfizz_ui.so -d sfizz.lv2/Contents/libs/ -p @loader_path/../libs/
|
|
||||||
cd "${TRAVIS_BUILD_DIR}/build"
|
|
||||||
|
|
||||||
# Bundle VST3 dependencies
|
|
||||||
cd "${INSTALL_DIR}"/Library/Audio/Plug-Ins/VST3
|
|
||||||
dylibbundler -od -b -x sfizz.vst3/Contents/MacOS/sfizz -d sfizz.vst3/Contents/libs/ -p @loader_path/../libs/
|
|
||||||
cd "${TRAVIS_BUILD_DIR}/build"
|
|
||||||
|
|
||||||
# Bundle AU dependencies
|
|
||||||
cd "${INSTALL_DIR}"/Library/Audio/Plug-Ins/Components
|
|
||||||
dylibbundler -od -b -x sfizz.component/Contents/Resources/plugin.vst3/Contents/MacOS/sfizz -d sfizz.component/Contents/Resources/plugin.vst3/Contents/libs/ -p @loader_path/../libs/
|
|
||||||
cd "${TRAVIS_BUILD_DIR}/build"
|
|
||||||
|
|
||||||
#
|
|
||||||
tar -zcvf "${INSTALL_DIR}.tar.gz" ${INSTALL_DIR}
|
|
||||||
|
|
||||||
# Only release a tarball if there is a tag
|
|
||||||
if [[ ${TRAVIS_TAG} != "" ]]; then
|
|
||||||
mv "${INSTALL_DIR}.tar.gz" ${TRAVIS_BUILD_DIR}
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd "${TRAVIS_BUILD_DIR}"
|
|
||||||
|
|
@ -8,7 +8,7 @@ else()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
project (sfizz VERSION 0.5.0 LANGUAGES CXX C)
|
project (sfizz VERSION 0.5.1 LANGUAGES CXX C)
|
||||||
set (PROJECT_DESCRIPTION "A library to load SFZ description files and use them to render music.")
|
set (PROJECT_DESCRIPTION "A library to load SFZ description files and use them to render music.")
|
||||||
|
|
||||||
# External configuration CMake scripts
|
# External configuration CMake scripts
|
||||||
|
|
@ -38,6 +38,9 @@ include (SfizzConfig)
|
||||||
# Don't use IPO in non Release builds
|
# Don't use IPO in non Release builds
|
||||||
include (CheckIPO)
|
include (CheckIPO)
|
||||||
|
|
||||||
|
# Dylib bunder for macOS
|
||||||
|
include (BundleDylibs)
|
||||||
|
|
||||||
# Add Abseil
|
# Add Abseil
|
||||||
add_subdirectory (external/abseil-cpp EXCLUDE_FROM_ALL)
|
add_subdirectory (external/abseil-cpp EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ install:
|
||||||
- cmd: vcpkg install libsndfile:%VCPKG_TRIPLET%
|
- cmd: vcpkg install libsndfile:%VCPKG_TRIPLET%
|
||||||
|
|
||||||
before_build:
|
before_build:
|
||||||
- cmd: git submodule update --init
|
- cmd: git submodule update --init --recursive
|
||||||
- cmd: mkdir CMakeBuild
|
- cmd: mkdir CMakeBuild
|
||||||
- cmd: cd CMakeBuild
|
- cmd: cd CMakeBuild
|
||||||
- cmd: cmake .. -G"Visual Studio 16 2019" -A"%platform%" -DSFIZZ_JACK=OFF -DSFIZZ_BENCHMARKS=OFF -DSFIZZ_TESTS=OFF -DSFIZZ_LV2=ON -DSFIZZ_VST=ON -DCMAKE_BUILD_TYPE=Release -DVCPKG_TARGET_TRIPLET=%VCPKG_TRIPLET% -DCMAKE_TOOLCHAIN_FILE=C:/Tools/vcpkg/scripts/buildsystems/vcpkg.cmake
|
- cmd: cmake .. -G"Visual Studio 16 2019" -A"%platform%" -DSFIZZ_JACK=OFF -DSFIZZ_BENCHMARKS=OFF -DSFIZZ_TESTS=OFF -DSFIZZ_LV2=ON -DSFIZZ_VST=ON -DCMAKE_BUILD_TYPE=Release -DVCPKG_TARGET_TRIPLET=%VCPKG_TRIPLET% -DCMAKE_TOOLCHAIN_FILE=C:/Tools/vcpkg/scripts/buildsystems/vcpkg.cmake
|
||||||
|
|
|
||||||
32
cmake/BundleDylibs.cmake
Normal file
32
cmake/BundleDylibs.cmake
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Dylib bundler for macOS
|
||||||
|
# Requires the external program "dylibbundler"
|
||||||
|
|
||||||
|
if(APPLE)
|
||||||
|
find_program(DYLIBBUNDLER_PROGRAM "dylibbundler")
|
||||||
|
if(NOT DYLIBBUNDLER_PROGRAM)
|
||||||
|
message(WARNING "The installation helper \"dylibbundler\" is not available.")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
function(bundle_dylibs NAME PATH)
|
||||||
|
if(NOT APPLE OR NOT DYLIBBUNDLER_PROGRAM)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(_relative_libdir "../libs")
|
||||||
|
|
||||||
|
get_filename_component(_dir "${PATH}" DIRECTORY)
|
||||||
|
set(_dir "${_dir}/${_relative_libdir}")
|
||||||
|
|
||||||
|
set(_script "${CMAKE_CURRENT_BINARY_DIR}/_bundle-dylibs.${NAME}.cmake")
|
||||||
|
|
||||||
|
file(WRITE "${_script}"
|
||||||
|
"execute_process(COMMAND \"${DYLIBBUNDLER_PROGRAM}\"
|
||||||
|
\"-cd\" \"-of\" \"-b\"
|
||||||
|
\"-x\" \"\$ENV{DESTDIR}${PATH}\"
|
||||||
|
\"-d\" \"\$ENV{DESTDIR}${_dir}\"
|
||||||
|
\"-p\" \"@loader_path/${_relative_libdir}/\")
|
||||||
|
")
|
||||||
|
|
||||||
|
install(SCRIPT "${_script}" ${ARGN})
|
||||||
|
endfunction()
|
||||||
|
|
@ -30,10 +30,13 @@ else()
|
||||||
set(LV2_UI_TYPE "X11UI")
|
set(LV2_UI_TYPE "X11UI")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (APPLE)
|
||||||
|
set (LV2PLUGIN_INSTALL_DIR "$ENV{HOME}/Library/Audio/Plug-Ins/LV2" CACHE STRING
|
||||||
|
"Install destination for LV2 bundle [default: $ENV{HOME}/Library/Audio/Plug-Ins/LV2]")
|
||||||
|
elseif (MSVC)
|
||||||
set (LV2PLUGIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lv2" CACHE STRING
|
set (LV2PLUGIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lv2" CACHE STRING
|
||||||
"Install destination for LV2 bundle [default: ${CMAKE_INSTALL_PREFIX}/lv2}]")
|
"Install destination for LV2 bundle [default: ${CMAKE_INSTALL_PREFIX}/lv2]")
|
||||||
else()
|
else()
|
||||||
set (LV2PLUGIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib/lv2" CACHE STRING
|
set (LV2PLUGIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib/lv2" CACHE STRING
|
||||||
"Install destination for LV2 bundle [default: ${CMAKE_INSTALL_PREFIX}/lib/lv2}]")
|
"Install destination for LV2 bundle [default: ${CMAKE_INSTALL_PREFIX}/lib/lv2]")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,17 @@ set (VSTPLUGIN_VENDOR "Paul Ferrand")
|
||||||
set (VSTPLUGIN_URL "http://sfztools.github.io/sfizz")
|
set (VSTPLUGIN_URL "http://sfztools.github.io/sfizz")
|
||||||
set (VSTPLUGIN_EMAIL "paul@ferrand.cc")
|
set (VSTPLUGIN_EMAIL "paul@ferrand.cc")
|
||||||
|
|
||||||
if (MSVC)
|
if (APPLE)
|
||||||
|
set (VSTPLUGIN_INSTALL_DIR "$ENV{HOME}/Library/Audio/Plug-Ins/VST3" CACHE STRING
|
||||||
|
"Install destination for VST bundle [default: $ENV{HOME}/Library/Audio/Plug-Ins/VST3]")
|
||||||
|
set (AUPLUGIN_INSTALL_DIR "$ENV{HOME}/Library/Audio/Plug-Ins/Components" CACHE STRING
|
||||||
|
"Install destination for AudioUnit bundle [default: $ENV{HOME}/Library/Audio/Plug-Ins/Components]")
|
||||||
|
elseif (MSVC)
|
||||||
set (VSTPLUGIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/vst3" CACHE STRING
|
set (VSTPLUGIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/vst3" CACHE STRING
|
||||||
"Install destination for VST bundle [default: ${CMAKE_INSTALL_PREFIX}/vst3}]")
|
"Install destination for VST bundle [default: ${CMAKE_INSTALL_PREFIX}/vst3]")
|
||||||
else()
|
else()
|
||||||
set (VSTPLUGIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib/vst3" CACHE STRING
|
set (VSTPLUGIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib/vst3" CACHE STRING
|
||||||
"Install destination for VST bundle [default: ${CMAKE_INSTALL_PREFIX}/lib/vst3}]")
|
"Install destination for VST bundle [default: ${CMAKE_INSTALL_PREFIX}/lib/vst3]")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (NOT VST3_SYSTEM_PROCESSOR)
|
if (NOT VST3_SYSTEM_PROCESSOR)
|
||||||
|
|
|
||||||
|
|
@ -194,11 +194,11 @@ else()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(${CMAKE_BUILD_TYPE} MATCHES "Debug")
|
if(${CMAKE_BUILD_TYPE} MATCHES "Debug")
|
||||||
target_compile_definitions(sfizz-vstgui PRIVATE "DEVELOPMENT")
|
target_compile_definitions(sfizz-vstgui PUBLIC "DEVELOPMENT")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(${CMAKE_BUILD_TYPE} MATCHES "Release")
|
if(${CMAKE_BUILD_TYPE} MATCHES "Release")
|
||||||
target_compile_definitions(sfizz-vstgui PRIVATE "RELEASE")
|
target_compile_definitions(sfizz-vstgui PUBLIC "RELEASE")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||||
|
|
@ -206,6 +206,10 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||||
set_property(TARGET sfizz-vstgui PROPERTY CXX_STANDARD 14)
|
set_property(TARGET sfizz-vstgui PROPERTY CXX_STANDARD 14)
|
||||||
# Windows 10 RS2 DDI for custom fonts
|
# Windows 10 RS2 DDI for custom fonts
|
||||||
target_compile_definitions(sfizz-vstgui PRIVATE "NTDDI_VERSION=0x0A000003")
|
target_compile_definitions(sfizz-vstgui PRIVATE "NTDDI_VERSION=0x0A000003")
|
||||||
|
# disable custom fonts while dwrite3 API is unavailable in MinGW
|
||||||
|
if(MINGW)
|
||||||
|
target_compile_definitions(sfizz-vstgui PRIVATE "VSTGUI_WIN32_CUSTOMFONT_SUPPORT=0")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||||
|
|
|
||||||
|
|
@ -423,7 +423,7 @@ void Editor::Impl::createFrameContents()
|
||||||
box->setBackgroundColor(theme->boxBackground);
|
box->setBackgroundColor(theme->boxBackground);
|
||||||
box->setTitleFontColor(theme->titleBoxText);
|
box->setTitleFontColor(theme->titleBoxText);
|
||||||
box->setTitleBackgroundColor(theme->titleBoxBackground);
|
box->setTitleBackgroundColor(theme->titleBoxBackground);
|
||||||
auto font = owned(new CFontDesc("Roboto", fontsize));
|
auto font = makeOwned<CFontDesc>("Roboto", fontsize);
|
||||||
box->setTitleFont(font);
|
box->setTitleFont(font);
|
||||||
return box;
|
return box;
|
||||||
};
|
};
|
||||||
|
|
@ -436,7 +436,7 @@ void Editor::Impl::createFrameContents()
|
||||||
lbl->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
lbl->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||||
lbl->setFontColor(theme->text);
|
lbl->setFontColor(theme->text);
|
||||||
lbl->setHoriAlign(align);
|
lbl->setHoriAlign(align);
|
||||||
auto font = owned(new CFontDesc("Roboto", fontsize));
|
auto font = makeOwned<CFontDesc>("Roboto", fontsize);
|
||||||
lbl->setFont(font);
|
lbl->setFont(font);
|
||||||
return lbl;
|
return lbl;
|
||||||
};
|
};
|
||||||
|
|
@ -463,7 +463,7 @@ void Editor::Impl::createFrameContents()
|
||||||
lbl->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
lbl->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||||
lbl->setFontColor(theme->text);
|
lbl->setFontColor(theme->text);
|
||||||
lbl->setHoriAlign(align);
|
lbl->setHoriAlign(align);
|
||||||
auto font = owned(new CFontDesc("Roboto", fontsize));
|
auto font = makeOwned<CFontDesc>("Roboto", fontsize);
|
||||||
lbl->setFont(font);
|
lbl->setFont(font);
|
||||||
return lbl;
|
return lbl;
|
||||||
};
|
};
|
||||||
|
|
@ -476,7 +476,7 @@ void Editor::Impl::createFrameContents()
|
||||||
#if 0
|
#if 0
|
||||||
auto createButton = [this](const CRect& bounds, int tag, const char* label, CHoriTxtAlign align, int fontsize) {
|
auto createButton = [this](const CRect& bounds, int tag, const char* label, CHoriTxtAlign align, int fontsize) {
|
||||||
CTextButton* button = new CTextButton(bounds, this, tag, label);
|
CTextButton* button = new CTextButton(bounds, this, tag, label);
|
||||||
auto font = owned(new CFontDesc("Roboto", fontsize));
|
auto font = makeOwned<CFontDesc>("Roboto", fontsize);
|
||||||
button->setFont(font);
|
button->setFont(font);
|
||||||
button->setTextAlignment(align);
|
button->setTextAlignment(align);
|
||||||
return button;
|
return button;
|
||||||
|
|
@ -484,7 +484,7 @@ void Editor::Impl::createFrameContents()
|
||||||
#endif
|
#endif
|
||||||
auto createClickableLabel = [this, &theme](const CRect& bounds, int tag, const char* label, CHoriTxtAlign align, int fontsize) {
|
auto createClickableLabel = [this, &theme](const CRect& bounds, int tag, const char* label, CHoriTxtAlign align, int fontsize) {
|
||||||
STextButton* button = new STextButton(bounds, this, tag, label);
|
STextButton* button = new STextButton(bounds, this, tag, label);
|
||||||
auto font = owned(new CFontDesc("Roboto", fontsize));
|
auto font = makeOwned<CFontDesc>("Roboto", fontsize);
|
||||||
button->setFont(font);
|
button->setFont(font);
|
||||||
button->setTextAlignment(align);
|
button->setTextAlignment(align);
|
||||||
button->setTextColor(theme->text);
|
button->setTextColor(theme->text);
|
||||||
|
|
@ -499,7 +499,7 @@ void Editor::Impl::createFrameContents()
|
||||||
};
|
};
|
||||||
auto createValueButton = [this, &theme](const CRect& bounds, int tag, const char* label, CHoriTxtAlign align, int fontsize) {
|
auto createValueButton = [this, &theme](const CRect& bounds, int tag, const char* label, CHoriTxtAlign align, int fontsize) {
|
||||||
STextButton* button = new STextButton(bounds, this, tag, label);
|
STextButton* button = new STextButton(bounds, this, tag, label);
|
||||||
auto font = owned(new CFontDesc("Roboto", fontsize));
|
auto font = makeOwned<CFontDesc>("Roboto", fontsize);
|
||||||
button->setFont(font);
|
button->setFont(font);
|
||||||
button->setTextAlignment(align);
|
button->setTextAlignment(align);
|
||||||
button->setTextColor(theme->valueText);
|
button->setTextColor(theme->valueText);
|
||||||
|
|
@ -515,7 +515,7 @@ void Editor::Impl::createFrameContents()
|
||||||
auto createValueMenu = [this, &theme](const CRect& bounds, int tag, const char*, CHoriTxtAlign align, int fontsize) {
|
auto createValueMenu = [this, &theme](const CRect& bounds, int tag, const char*, CHoriTxtAlign align, int fontsize) {
|
||||||
SValueMenu* vm = new SValueMenu(bounds, this, tag);
|
SValueMenu* vm = new SValueMenu(bounds, this, tag);
|
||||||
vm->setHoriAlign(align);
|
vm->setHoriAlign(align);
|
||||||
auto font = owned(new CFontDesc("Roboto", fontsize));
|
auto font = makeOwned<CFontDesc>("Roboto", fontsize);
|
||||||
vm->setFont(font);
|
vm->setFont(font);
|
||||||
vm->setFontColor(theme->valueText);
|
vm->setFontColor(theme->valueText);
|
||||||
vm->setBackColor(theme->valueBackground);
|
vm->setBackColor(theme->valueBackground);
|
||||||
|
|
@ -526,7 +526,7 @@ void Editor::Impl::createFrameContents()
|
||||||
};
|
};
|
||||||
auto createGlyphButton = [this, &theme](UTF8StringPtr glyph, const CRect& bounds, int tag, int fontsize) {
|
auto createGlyphButton = [this, &theme](UTF8StringPtr glyph, const CRect& bounds, int tag, int fontsize) {
|
||||||
STextButton* btn = new STextButton(bounds, this, tag, glyph);
|
STextButton* btn = new STextButton(bounds, this, tag, glyph);
|
||||||
btn->setFont(new CFontDesc("Sfizz Fluent System R20", fontsize));
|
btn->setFont(makeOwned<CFontDesc>("Sfizz Fluent System R20", fontsize));
|
||||||
btn->setTextColor(theme->icon);
|
btn->setTextColor(theme->icon);
|
||||||
btn->setHoverColor(theme->iconHighlight);
|
btn->setHoverColor(theme->iconHighlight);
|
||||||
btn->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
btn->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||||
|
|
@ -559,14 +559,14 @@ void Editor::Impl::createFrameContents()
|
||||||
};
|
};
|
||||||
auto createPiano = [](const CRect& bounds, int, const char*, CHoriTxtAlign, int fontsize) {
|
auto createPiano = [](const CRect& bounds, int, const char*, CHoriTxtAlign, int fontsize) {
|
||||||
SPiano* piano = new SPiano(bounds);
|
SPiano* piano = new SPiano(bounds);
|
||||||
auto font = owned(new CFontDesc("Roboto", fontsize));
|
auto font = makeOwned<CFontDesc>("Roboto", fontsize);
|
||||||
piano->setFont(font);
|
piano->setFont(font);
|
||||||
return piano;
|
return piano;
|
||||||
};
|
};
|
||||||
auto createChevronDropDown = [this, &theme](const CRect& bounds, int, const char*, CHoriTxtAlign, int fontsize) {
|
auto createChevronDropDown = [this, &theme](const CRect& bounds, int, const char*, CHoriTxtAlign, int fontsize) {
|
||||||
SActionMenu* menu = new SActionMenu(bounds, this);
|
SActionMenu* menu = new SActionMenu(bounds, this);
|
||||||
menu->setTitle(u8"\ue0d7");
|
menu->setTitle(u8"\ue0d7");
|
||||||
menu->setFont(new CFontDesc("Sfizz Fluent System R20", fontsize));
|
menu->setFont(makeOwned<CFontDesc>("Sfizz Fluent System R20", fontsize));
|
||||||
menu->setFontColor(theme->icon);
|
menu->setFontColor(theme->icon);
|
||||||
menu->setHoverColor(theme->iconHighlight);
|
menu->setHoverColor(theme->iconHighlight);
|
||||||
menu->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
menu->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ void SPiano::draw(CDrawContext* dc)
|
||||||
CRect textRect(
|
CRect textRect(
|
||||||
rect.left, dim.labelBounds.top,
|
rect.left, dim.labelBounds.top,
|
||||||
rect.right, dim.labelBounds.bottom);
|
rect.right, dim.labelBounds.bottom);
|
||||||
dc->setFont(font_);
|
dc->setFont(font);
|
||||||
dc->setFontColor(labelStroke_);
|
dc->setFontColor(labelStroke_);
|
||||||
std::string text = std::to_string(static_cast<int>(o) - 1);
|
std::string text = std::to_string(static_cast<int>(o) - 1);
|
||||||
dc->drawString(text.c_str(), textRect, kCenterText);
|
dc->drawString(text.c_str(), textRect, kCenterText);
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,12 @@ endif()
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
if (NOT MSVC)
|
if (NOT MSVC)
|
||||||
install (DIRECTORY ${PROJECT_BINARY_DIR} DESTINATION ${LV2PLUGIN_INSTALL_DIR}
|
install(DIRECTORY ${PROJECT_BINARY_DIR} DESTINATION ${LV2PLUGIN_INSTALL_DIR}
|
||||||
|
COMPONENT "lv2")
|
||||||
|
bundle_dylibs(lv2
|
||||||
|
"${LV2PLUGIN_INSTALL_DIR}/${PROJECT_NAME}.lv2/Contents/Binary/sfizz.so"
|
||||||
|
COMPONENT "lv2")
|
||||||
|
bundle_dylibs(lv2-ui
|
||||||
|
"${LV2PLUGIN_INSTALL_DIR}/${PROJECT_NAME}.lv2/Contents/Binary/sfizz_ui.so"
|
||||||
COMPONENT "lv2")
|
COMPONENT "lv2")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,26 @@ private:
|
||||||
void uiTouch(EditId id, bool t);
|
void uiTouch(EditId id, bool t);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
static bool fixBundlePath(std::string& path)
|
||||||
|
{
|
||||||
|
// go up some directories until reaching the *.lv2 directory
|
||||||
|
bool valid = false;
|
||||||
|
while (!valid && !path.empty()) {
|
||||||
|
if (path.back() == '\\' || path.back() == '/')
|
||||||
|
path.pop_back();
|
||||||
|
else if (path.size() > 4 && !memcmp(".lv2", path.data() + path.size() - 4, 4))
|
||||||
|
valid = true;
|
||||||
|
else {
|
||||||
|
path.pop_back();
|
||||||
|
while (!path.empty() && path.back() != '\\' && path.back() != '/')
|
||||||
|
path.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static LV2UI_Handle
|
static LV2UI_Handle
|
||||||
instantiate(const LV2UI_Descriptor *descriptor,
|
instantiate(const LV2UI_Descriptor *descriptor,
|
||||||
const char *plugin_uri,
|
const char *plugin_uri,
|
||||||
|
|
@ -178,8 +198,16 @@ instantiate(const LV2UI_Descriptor *descriptor,
|
||||||
// name, and appending "Contents/Resources" (not overridable)
|
// name, and appending "Contents/Resources" (not overridable)
|
||||||
// * on Windows, the folder is set programmatically
|
// * on Windows, the folder is set programmatically
|
||||||
// * on macOS, resource files are looked up using CFBundle APIs
|
// * on macOS, resource files are looked up using CFBundle APIs
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
IWin32PlatformFrame::setResourceBasePath((std::string(bundle_path) + "\\Contents\\Resources\\").c_str());
|
// some hosts give us the DLL path instead of the bundle path,
|
||||||
|
// so we have to work around that.
|
||||||
|
std::string realBundlePath { bundle_path };
|
||||||
|
if (!fixBundlePath(realBundlePath))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
std::string resourcePath = realBundlePath + "\\Contents\\Resources\\";
|
||||||
|
IWin32PlatformFrame::setResourceBasePath(resourcePath.c_str());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// makes labels refresh correctly
|
// makes labels refresh correctly
|
||||||
|
|
|
||||||
BIN
screenshot.png
BIN
screenshot.png
Binary file not shown.
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 44 KiB |
|
|
@ -47,7 +47,29 @@
|
||||||
#endif
|
#endif
|
||||||
#include "threadpool/ThreadPool.h"
|
#include "threadpool/ThreadPool.h"
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
static ThreadPool threadPool { std::thread::hardware_concurrency() > 2 ? std::thread::hardware_concurrency() - 2 : 1 };
|
|
||||||
|
static std::weak_ptr<ThreadPool> globalThreadPoolWeakPtr;
|
||||||
|
static std::mutex globalThreadPoolMutex;
|
||||||
|
|
||||||
|
static std::shared_ptr<ThreadPool> globalThreadPool()
|
||||||
|
{
|
||||||
|
std::shared_ptr<ThreadPool> threadPool;
|
||||||
|
|
||||||
|
threadPool = globalThreadPoolWeakPtr.lock();
|
||||||
|
if (threadPool)
|
||||||
|
return threadPool;
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(globalThreadPoolMutex);
|
||||||
|
threadPool = globalThreadPoolWeakPtr.lock();
|
||||||
|
if (threadPool)
|
||||||
|
return threadPool;
|
||||||
|
|
||||||
|
unsigned numThreads = std::thread::hardware_concurrency();
|
||||||
|
numThreads = (numThreads > 2) ? (numThreads - 2) : 1;
|
||||||
|
threadPool.reset(new ThreadPool(numThreads));
|
||||||
|
globalThreadPoolWeakPtr = threadPool;
|
||||||
|
return threadPool;
|
||||||
|
}
|
||||||
|
|
||||||
void readBaseFile(sfz::AudioReader& reader, sfz::FileAudioBuffer& output, uint32_t numFrames)
|
void readBaseFile(sfz::AudioReader& reader, sfz::FileAudioBuffer& output, uint32_t numFrames)
|
||||||
{
|
{
|
||||||
|
|
@ -96,7 +118,7 @@ void streamFromFile(sfz::AudioReader& reader, uint32_t numFrames, sfz::Oversampl
|
||||||
}
|
}
|
||||||
|
|
||||||
sfz::FilePool::FilePool(sfz::Logger& logger)
|
sfz::FilePool::FilePool(sfz::Logger& logger)
|
||||||
: logger(logger)
|
: logger(logger), threadPool(globalThreadPool())
|
||||||
{
|
{
|
||||||
loadingJobs.reserve(config::maxVoices);
|
loadingJobs.reserve(config::maxVoices);
|
||||||
lastUsedFiles.reserve(config::maxVoices);
|
lastUsedFiles.reserve(config::maxVoices);
|
||||||
|
|
@ -320,9 +342,9 @@ sfz::FileDataHolder sfz::FilePool::loadFile(const FileId& fileId) noexcept
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sfz::FileDataHolder sfz::FilePool::getFilePromise(const FileId& fileId) noexcept
|
sfz::FileDataHolder sfz::FilePool::getFilePromise(const std::shared_ptr<FileId>& fileId) noexcept
|
||||||
{
|
{
|
||||||
const auto preloaded = preloadedFiles.find(fileId);
|
const auto preloaded = preloadedFiles.find(*fileId);
|
||||||
if (preloaded == preloadedFiles.end()) {
|
if (preloaded == preloadedFiles.end()) {
|
||||||
DBG("[sfizz] File not found in the preloaded files: " << fileId);
|
DBG("[sfizz] File not found in the preloaded files: " << fileId);
|
||||||
return {};
|
return {};
|
||||||
|
|
@ -359,14 +381,20 @@ void sfz::FilePool::loadingJob(QueuedFileData data) noexcept
|
||||||
{
|
{
|
||||||
raiseCurrentThreadPriority();
|
raiseCurrentThreadPriority();
|
||||||
|
|
||||||
|
std::shared_ptr<FileId> id = data.id.lock();
|
||||||
|
if (!id) {
|
||||||
|
// file ID was nulled, it means the region was deleted, ignore
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const auto loadStartTime = std::chrono::high_resolution_clock::now();
|
const auto loadStartTime = std::chrono::high_resolution_clock::now();
|
||||||
const auto waitDuration = loadStartTime - data.queuedTime;
|
const auto waitDuration = loadStartTime - data.queuedTime;
|
||||||
const fs::path file { rootDirectory / data.id.filename() };
|
const fs::path file { rootDirectory / id->filename() };
|
||||||
std::error_code readError;
|
std::error_code readError;
|
||||||
AudioReaderPtr reader = createAudioReader(file, data.id.isReverse(), &readError);
|
AudioReaderPtr reader = createAudioReader(file, id->isReverse(), &readError);
|
||||||
|
|
||||||
if (readError) {
|
if (readError) {
|
||||||
DBG("[sfizz] libsndfile errored for " << data.id << " with message " << readError.message());
|
DBG("[sfizz] libsndfile errored for " << *id << " with message " << readError.message());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -376,7 +404,7 @@ void sfz::FilePool::loadingJob(QueuedFileData data) noexcept
|
||||||
while (currentStatus == FileData::Status::Invalid) {
|
while (currentStatus == FileData::Status::Invalid) {
|
||||||
// Spin until the state changes
|
// Spin until the state changes
|
||||||
if (spinCounter > 1024) {
|
if (spinCounter > 1024) {
|
||||||
DBG("[sfizz] " << data.id << " is stuck on Invalid? Leaving the load");
|
DBG("[sfizz] " << *id << " is stuck on Invalid? Leaving the load");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -396,18 +424,21 @@ void sfz::FilePool::loadingJob(QueuedFileData data) noexcept
|
||||||
const auto frames = static_cast<uint32_t>(reader->frames());
|
const auto frames = static_cast<uint32_t>(reader->frames());
|
||||||
streamFromFile(*reader, frames, oversamplingFactor, data.data->fileData, &data.data->availableFrames);
|
streamFromFile(*reader, frames, oversamplingFactor, data.data->fileData, &data.data->availableFrames);
|
||||||
const auto loadDuration = std::chrono::high_resolution_clock::now() - loadStartTime;
|
const auto loadDuration = std::chrono::high_resolution_clock::now() - loadStartTime;
|
||||||
logger.logFileTime(waitDuration, loadDuration, frames, data.id.filename());
|
logger.logFileTime(waitDuration, loadDuration, frames, id->filename());
|
||||||
|
|
||||||
data.data->status = FileData::Status::Done;
|
data.data->status = FileData::Status::Done;
|
||||||
|
|
||||||
std::lock_guard<SpinMutex> guard { lastUsedMutex };
|
std::lock_guard<SpinMutex> guard { garbageAndLastUsedMutex };
|
||||||
if (absl::c_find(lastUsedFiles, data.id) == lastUsedFiles.end())
|
if (absl::c_find(lastUsedFiles, *id) == lastUsedFiles.end())
|
||||||
lastUsedFiles.push_back(data.id);
|
lastUsedFiles.push_back(*id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::FilePool::clear()
|
void sfz::FilePool::clear()
|
||||||
{
|
{
|
||||||
|
std::lock_guard<SpinMutex> guard { garbageAndLastUsedMutex };
|
||||||
emptyFileLoadingQueues();
|
emptyFileLoadingQueues();
|
||||||
|
garbageToCollect.clear();
|
||||||
|
lastUsedFiles.clear();
|
||||||
preloadedFiles.clear();
|
preloadedFiles.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -464,23 +495,16 @@ bool is_ready(std::future<R> const& f)
|
||||||
void sfz::FilePool::dispatchingJob() noexcept
|
void sfz::FilePool::dispatchingJob() noexcept
|
||||||
{
|
{
|
||||||
QueuedFileData queuedData;
|
QueuedFileData queuedData;
|
||||||
while (dispatchFlag) {
|
while (dispatchBarrier.wait(), dispatchFlag) {
|
||||||
dispatchBarrier.wait();
|
|
||||||
|
|
||||||
if (emptyQueueFlag) {
|
|
||||||
while (filesToLoad.try_pop(queuedData)) {
|
|
||||||
// pass
|
|
||||||
}
|
|
||||||
semEmptyQueueFinished.post();
|
|
||||||
emptyQueueFlag = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> guard { loadingJobsMutex };
|
std::lock_guard<std::mutex> guard { loadingJobsMutex };
|
||||||
|
|
||||||
if (filesToLoad.try_pop(queuedData)) {
|
if (filesToLoad.try_pop(queuedData)) {
|
||||||
loadingJobs.push_back(
|
if (queuedData.id.expired()) {
|
||||||
threadPool.enqueue([this](const QueuedFileData& data) { loadingJob(data); }, queuedData));
|
// file ID was nulled, it means the region was deleted, ignore
|
||||||
|
}
|
||||||
|
else
|
||||||
|
loadingJobs.push_back(
|
||||||
|
threadPool->enqueue([this](const QueuedFileData& data) { loadingJob(data); }, queuedData));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear finished jobs
|
// Clear finished jobs
|
||||||
|
|
@ -492,29 +516,12 @@ void sfz::FilePool::dispatchingJob() noexcept
|
||||||
|
|
||||||
void sfz::FilePool::garbageJob() noexcept
|
void sfz::FilePool::garbageJob() noexcept
|
||||||
{
|
{
|
||||||
while (garbageFlag) {
|
while (semGarbageBarrier.wait(), garbageFlag) {
|
||||||
semGarbageBarrier.wait();
|
std::lock_guard<SpinMutex> guard { garbageAndLastUsedMutex };
|
||||||
{
|
garbageToCollect.clear();
|
||||||
std::lock_guard<SpinMutex> guard { garbageMutex };
|
|
||||||
for (auto& g: garbageToCollect)
|
|
||||||
g.reset();
|
|
||||||
|
|
||||||
garbageToCollect.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::FilePool::emptyFileLoadingQueues() noexcept
|
|
||||||
{
|
|
||||||
ASSERT(dispatchFlag);
|
|
||||||
emptyQueueFlag = true;
|
|
||||||
std::error_code ec;
|
|
||||||
dispatchBarrier.post(ec);
|
|
||||||
|
|
||||||
if (!ec)
|
|
||||||
semEmptyQueueFinished.wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
void sfz::FilePool::waitForBackgroundLoading() noexcept
|
void sfz::FilePool::waitForBackgroundLoading() noexcept
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> guard { loadingJobsMutex };
|
std::lock_guard<std::mutex> guard { loadingJobsMutex };
|
||||||
|
|
@ -580,9 +587,8 @@ void sfz::FilePool::setRamLoading(bool loadInRam) noexcept
|
||||||
|
|
||||||
void sfz::FilePool::triggerGarbageCollection() noexcept
|
void sfz::FilePool::triggerGarbageCollection() noexcept
|
||||||
{
|
{
|
||||||
const std::unique_lock<SpinMutex> lastUsedLock { lastUsedMutex, std::try_to_lock };
|
const std::unique_lock<SpinMutex> guard { garbageAndLastUsedMutex, std::try_to_lock };
|
||||||
const std::unique_lock<SpinMutex> garbageLock { garbageMutex, std::try_to_lock };
|
if (!guard.owns_lock())
|
||||||
if (!lastUsedLock.owns_lock() || !garbageLock.owns_lock())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto now = std::chrono::high_resolution_clock::now();
|
const auto now = std::chrono::high_resolution_clock::now();
|
||||||
|
|
@ -590,7 +596,14 @@ void sfz::FilePool::triggerGarbageCollection() noexcept
|
||||||
if (garbageToCollect.size() == garbageToCollect.capacity())
|
if (garbageToCollect.size() == garbageToCollect.capacity())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto& data = preloadedFiles[id];
|
auto it = preloadedFiles.find(id);
|
||||||
|
if (it == preloadedFiles.end()) {
|
||||||
|
// Getting here means that the preloadedFiles got changed (probably cleared)
|
||||||
|
// while the lastUsedFiles were untouched.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sfz::FileData& data = it->second;
|
||||||
if (data.status == FileData::Status::Preloaded)
|
if (data.status == FileData::Status::Preloaded)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <future>
|
#include <future>
|
||||||
#include "utility/SpinMutex.h"
|
#include "utility/SpinMutex.h"
|
||||||
|
class ThreadPool;
|
||||||
|
|
||||||
namespace sfz {
|
namespace sfz {
|
||||||
using FileAudioBuffer = AudioBuffer<float, 2, config::defaultAlignment,
|
using FileAudioBuffer = AudioBuffer<float, 2, config::defaultAlignment,
|
||||||
|
|
@ -262,7 +263,7 @@ public:
|
||||||
* @param fileId the file to preload
|
* @param fileId the file to preload
|
||||||
* @return FileDataHolder a file data handle
|
* @return FileDataHolder a file data handle
|
||||||
*/
|
*/
|
||||||
FileDataHolder getFilePromise(const FileId& fileId) noexcept;
|
FileDataHolder getFilePromise(const std::shared_ptr<FileId>& fileId) noexcept;
|
||||||
/**
|
/**
|
||||||
* @brief Change the preloading size. This will trigger a full
|
* @brief Change the preloading size. This will trigger a full
|
||||||
* reload of all samples, so don't call it on the audio thread.
|
* reload of all samples, so don't call it on the audio thread.
|
||||||
|
|
@ -295,7 +296,11 @@ public:
|
||||||
* method on the audio thread as it will spinlock.
|
* method on the audio thread as it will spinlock.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void emptyFileLoadingQueues() noexcept;
|
void emptyFileLoadingQueues() noexcept
|
||||||
|
{
|
||||||
|
// nothing to do in this implementation,
|
||||||
|
// deleting the region and its sample ID take care of it
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @brief Wait for the background loading to finish for all promises
|
* @brief Wait for the background loading to finish for all promises
|
||||||
* in the queue.
|
* in the queue.
|
||||||
|
|
@ -330,9 +335,7 @@ private:
|
||||||
// Signals
|
// Signals
|
||||||
volatile bool dispatchFlag { true };
|
volatile bool dispatchFlag { true };
|
||||||
volatile bool garbageFlag { true };
|
volatile bool garbageFlag { true };
|
||||||
volatile bool emptyQueueFlag { false };
|
|
||||||
RTSemaphore dispatchBarrier;
|
RTSemaphore dispatchBarrier;
|
||||||
RTSemaphore semEmptyQueueFinished;
|
|
||||||
RTSemaphore semGarbageBarrier;
|
RTSemaphore semGarbageBarrier;
|
||||||
|
|
||||||
// Structures for the background loaders
|
// Structures for the background loaders
|
||||||
|
|
@ -340,13 +343,13 @@ private:
|
||||||
{
|
{
|
||||||
using TimePoint = std::chrono::time_point<std::chrono::high_resolution_clock>;
|
using TimePoint = std::chrono::time_point<std::chrono::high_resolution_clock>;
|
||||||
QueuedFileData() = default;
|
QueuedFileData() = default;
|
||||||
QueuedFileData(FileId id, FileData* data, TimePoint queuedTime)
|
QueuedFileData(std::weak_ptr<FileId> id, FileData* data, TimePoint queuedTime)
|
||||||
: id(id), data(data), queuedTime(queuedTime) {}
|
: id(id), data(data), queuedTime(queuedTime) {}
|
||||||
QueuedFileData(const QueuedFileData&) = default;
|
QueuedFileData(const QueuedFileData&) = default;
|
||||||
QueuedFileData& operator=(const QueuedFileData&) = default;
|
QueuedFileData& operator=(const QueuedFileData&) = default;
|
||||||
QueuedFileData(QueuedFileData&&) = default;
|
QueuedFileData(QueuedFileData&&) = default;
|
||||||
QueuedFileData& operator=(QueuedFileData&&) = default;
|
QueuedFileData& operator=(QueuedFileData&&) = default;
|
||||||
FileId id {};
|
std::weak_ptr<FileId> id;
|
||||||
FileData* data { nullptr };
|
FileData* data { nullptr };
|
||||||
TimePoint queuedTime {};
|
TimePoint queuedTime {};
|
||||||
};
|
};
|
||||||
|
|
@ -359,11 +362,12 @@ private:
|
||||||
std::thread dispatchThread { &FilePool::dispatchingJob, this };
|
std::thread dispatchThread { &FilePool::dispatchingJob, this };
|
||||||
std::thread garbageThread { &FilePool::garbageJob, this };
|
std::thread garbageThread { &FilePool::garbageJob, this };
|
||||||
|
|
||||||
SpinMutex lastUsedMutex;
|
SpinMutex garbageAndLastUsedMutex;
|
||||||
std::vector<FileId> lastUsedFiles;
|
std::vector<FileId> lastUsedFiles;
|
||||||
SpinMutex garbageMutex;
|
|
||||||
std::vector<FileAudioBuffer> garbageToCollect;
|
std::vector<FileAudioBuffer> garbageToCollect;
|
||||||
|
|
||||||
|
std::shared_ptr<ThreadPool> threadPool;
|
||||||
|
|
||||||
// Preloaded data
|
// Preloaded data
|
||||||
absl::flat_hash_map<FileId, FileData> preloadedFiles;
|
absl::flat_hash_map<FileId, FileData> preloadedFiles;
|
||||||
absl::flat_hash_map<FileId, FileData> loadedFiles;
|
absl::flat_hash_map<FileId, FileData> loadedFiles;
|
||||||
|
|
|
||||||
|
|
@ -49,10 +49,10 @@ inline void tickPan(const float* pan, float* leftBuffer, float* rightBuffer)
|
||||||
|
|
||||||
void pan(const float* panEnvelope, float* leftBuffer, float* rightBuffer, unsigned size) noexcept
|
void pan(const float* panEnvelope, float* leftBuffer, float* rightBuffer, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = panEnvelope + size;
|
const auto* sentinel = panEnvelope + size;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_NEON
|
#if SFIZZ_HAVE_NEON
|
||||||
const auto firstAligned = prevAligned<ByteAlignment>(panEnvelope + TypeAlignment - 1);
|
const auto* firstAligned = prevAligned<ByteAlignment>(panEnvelope + TypeAlignment - 1);
|
||||||
|
|
||||||
if (willAlign<ByteAlignment>(panEnvelope, leftBuffer, rightBuffer) && (firstAligned < sentinel)) {
|
if (willAlign<ByteAlignment>(panEnvelope, leftBuffer, rightBuffer) && (firstAligned < sentinel)) {
|
||||||
while (panEnvelope < firstAligned) {
|
while (panEnvelope < firstAligned) {
|
||||||
|
|
@ -63,7 +63,7 @@ void pan(const float* panEnvelope, float* leftBuffer, float* rightBuffer, unsign
|
||||||
uint32_t indices[TypeAlignment];
|
uint32_t indices[TypeAlignment];
|
||||||
float leftPan[TypeAlignment];
|
float leftPan[TypeAlignment];
|
||||||
float rightPan[TypeAlignment];
|
float rightPan[TypeAlignment];
|
||||||
const auto lastAligned = prevAligned<ByteAlignment>(sentinel);
|
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
||||||
while (panEnvelope < lastAligned) {
|
while (panEnvelope < lastAligned) {
|
||||||
float32x4_t mmPan = vld1q_f32(panEnvelope);
|
float32x4_t mmPan = vld1q_f32(panEnvelope);
|
||||||
mmPan = vaddq_f32(mmPan, vdupq_n_f32(1.0f));
|
mmPan = vaddq_f32(mmPan, vdupq_n_f32(1.0f));
|
||||||
|
|
@ -112,10 +112,10 @@ inline void tickWidth(const float* width, float* leftBuffer, float* rightBuffer)
|
||||||
|
|
||||||
void width(const float* widthEnvelope, float* leftBuffer, float* rightBuffer, unsigned size) noexcept
|
void width(const float* widthEnvelope, float* leftBuffer, float* rightBuffer, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = widthEnvelope + size;
|
const auto* sentinel = widthEnvelope + size;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_NEON
|
#if SFIZZ_HAVE_NEON
|
||||||
const auto firstAligned = prevAligned<ByteAlignment>(widthEnvelope + TypeAlignment - 1);
|
const auto* firstAligned = prevAligned<ByteAlignment>(widthEnvelope + TypeAlignment - 1);
|
||||||
|
|
||||||
if (willAlign<ByteAlignment>(widthEnvelope, leftBuffer, rightBuffer) && firstAligned < sentinel) {
|
if (willAlign<ByteAlignment>(widthEnvelope, leftBuffer, rightBuffer) && firstAligned < sentinel) {
|
||||||
while (widthEnvelope < firstAligned) {
|
while (widthEnvelope < firstAligned) {
|
||||||
|
|
@ -126,7 +126,7 @@ void width(const float* widthEnvelope, float* leftBuffer, float* rightBuffer, un
|
||||||
uint32_t indices[TypeAlignment];
|
uint32_t indices[TypeAlignment];
|
||||||
float coeff1[TypeAlignment];
|
float coeff1[TypeAlignment];
|
||||||
float coeff2[TypeAlignment];
|
float coeff2[TypeAlignment];
|
||||||
const auto lastAligned = prevAligned<ByteAlignment>(sentinel);
|
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
||||||
while (widthEnvelope < lastAligned) {
|
while (widthEnvelope < lastAligned) {
|
||||||
float32x4_t mmWidth = vld1q_f32(widthEnvelope);
|
float32x4_t mmWidth = vld1q_f32(widthEnvelope);
|
||||||
mmWidth = vaddq_f32(mmWidth, vdupq_n_f32(1.0f));
|
mmWidth = vaddq_f32(mmWidth, vdupq_n_f32(1.0f));
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
|
||||||
else
|
else
|
||||||
filename = absl::StrCat(defaultPath, absl::StrReplaceAll(trimmedSample, { { "\\", "/" } }));
|
filename = absl::StrCat(defaultPath, absl::StrReplaceAll(trimmedSample, { { "\\", "/" } }));
|
||||||
|
|
||||||
sampleId = FileId(std::move(filename), sampleId.isReverse());
|
*sampleId = FileId(std::move(filename), sampleId->isReverse());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case hash("sample_quality"):
|
case hash("sample_quality"):
|
||||||
|
|
@ -88,7 +88,7 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case hash("direction"):
|
case hash("direction"):
|
||||||
sampleId = sampleId.reversed(opcode.value == "reverse");
|
*sampleId = sampleId->reversed(opcode.value == "reverse");
|
||||||
break;
|
break;
|
||||||
case hash("delay"):
|
case hash("delay"):
|
||||||
setValueFromOpcode(opcode, delay, Default::delayRange);
|
setValueFromOpcode(opcode, delay, Default::delayRange);
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ struct Region {
|
||||||
* @return true
|
* @return true
|
||||||
* @return false
|
* @return false
|
||||||
*/
|
*/
|
||||||
bool isGenerator() const noexcept { return sampleId.filename().size() > 0 ? sampleId.filename()[0] == '*' : false; }
|
bool isGenerator() const noexcept { return sampleId->filename().size() > 0 ? sampleId->filename()[0] == '*' : false; }
|
||||||
/**
|
/**
|
||||||
* @brief Is an oscillator (generator or wavetable)?
|
* @brief Is an oscillator (generator or wavetable)?
|
||||||
*
|
*
|
||||||
|
|
@ -308,7 +308,7 @@ struct Region {
|
||||||
const NumericId<Region> id;
|
const NumericId<Region> id;
|
||||||
|
|
||||||
// Sound source: sample playback
|
// Sound source: sample playback
|
||||||
FileId sampleId {}; // Sample
|
std::shared_ptr<FileId> sampleId { new FileId }; // Sample
|
||||||
absl::optional<int> sampleQuality {};
|
absl::optional<int> sampleQuality {};
|
||||||
float delay { Default::delay }; // delay
|
float delay { Default::delay }; // delay
|
||||||
float delayRandom { Default::delayRandom }; // delay_random
|
float delayRandom { Default::delayRandom }; // delay_random
|
||||||
|
|
|
||||||
|
|
@ -663,10 +663,10 @@ void sfzInterpolationCast(absl::Span<const T> floatJumps, absl::Span<int> jumps,
|
||||||
SFIZZ_CHECK(jumps.size() >= floatJumps.size());
|
SFIZZ_CHECK(jumps.size() >= floatJumps.size());
|
||||||
SFIZZ_CHECK(jumps.size() == coeffs.size());
|
SFIZZ_CHECK(jumps.size() == coeffs.size());
|
||||||
|
|
||||||
auto floatJump = floatJumps.data();
|
auto* floatJump = floatJumps.data();
|
||||||
auto jump = jumps.data();
|
auto* jump = jumps.data();
|
||||||
auto coeff = coeffs.data();
|
auto* coeff = coeffs.data();
|
||||||
const auto sentinel = floatJump + min(floatJumps.size(), jumps.size(), coeffs.size());
|
const auto* sentinel = floatJump + min(floatJumps.size(), jumps.size(), coeffs.size());
|
||||||
|
|
||||||
while (floatJump < sentinel)
|
while (floatJump < sentinel)
|
||||||
_internals::snippetSFZInterpolationCast(floatJump, jump, coeff);
|
_internals::snippetSFZInterpolationCast(floatJump, jump, coeff);
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Removes the whitespace on a string_view in place
|
* @brief Removes the whitespace on a string_view in place
|
||||||
|
|
@ -45,6 +46,18 @@ inline absl::string_view trim(absl::string_view s)
|
||||||
constexpr uint64_t Fnv1aBasis = 0x811C9DC5;
|
constexpr uint64_t Fnv1aBasis = 0x811C9DC5;
|
||||||
constexpr uint64_t Fnv1aPrime = 0x01000193;
|
constexpr uint64_t Fnv1aPrime = 0x01000193;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Hash a single byte.
|
||||||
|
*
|
||||||
|
* @param s the input string to be hashed
|
||||||
|
* @param h the hashing seed to use
|
||||||
|
* @return uint64_t
|
||||||
|
*/
|
||||||
|
constexpr uint64_t hashByte(uint8_t byte, uint64_t h = Fnv1aBasis)
|
||||||
|
{
|
||||||
|
return (h ^ byte) * Fnv1aPrime;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compile-time hashing function to be used mostly with switch/case statements.
|
* @brief Compile-time hashing function to be used mostly with switch/case statements.
|
||||||
*
|
*
|
||||||
|
|
@ -56,7 +69,7 @@ constexpr uint64_t Fnv1aPrime = 0x01000193;
|
||||||
*/
|
*/
|
||||||
constexpr uint64_t hash(absl::string_view s, uint64_t h = Fnv1aBasis)
|
constexpr uint64_t hash(absl::string_view s, uint64_t h = Fnv1aBasis)
|
||||||
{
|
{
|
||||||
return (s.length() == 0) ? h : hash( { s.data() + 1, s.length() - 1 }, (h ^ s.front()) * Fnv1aPrime );
|
return (s.length() == 0) ? h : hash({ s.data() + 1, s.length() - 1 }, hashByte(s.front(), h));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -73,7 +86,7 @@ constexpr uint64_t hashNoAmpersand(absl::string_view s, uint64_t h = Fnv1aBasis)
|
||||||
return (s.length() == 0) ? h : (
|
return (s.length() == 0) ? h : (
|
||||||
(s.front() == '&')
|
(s.front() == '&')
|
||||||
? hashNoAmpersand( { s.data() + 1, s.length() - 1 }, h )
|
? hashNoAmpersand( { s.data() + 1, s.length() - 1 }, h )
|
||||||
: hashNoAmpersand( { s.data() + 1, s.length() - 1 }, (h ^ s.front()) * Fnv1aPrime )
|
: hashNoAmpersand( { s.data() + 1, s.length() - 1 }, hashByte(s.front(), h) )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,8 @@ void sfz::Synth::buildRegion(const std::vector<Opcode>& regionOpcodes)
|
||||||
|
|
||||||
void sfz::Synth::clear()
|
void sfz::Synth::clear()
|
||||||
{
|
{
|
||||||
const std::lock_guard<SpinMutex> disableCallback { callbackGuard };
|
// Clear the background queues before removing everyone
|
||||||
|
resources.filePool.waitForBackgroundLoading();
|
||||||
|
|
||||||
for (auto& voice : voices)
|
for (auto& voice : voices)
|
||||||
voice->reset();
|
voice->reset();
|
||||||
|
|
@ -470,10 +471,10 @@ void sfz::Synth::handleEffectOpcodes(const std::vector<Opcode>& rawMembers)
|
||||||
|
|
||||||
bool sfz::Synth::loadSfzFile(const fs::path& file)
|
bool sfz::Synth::loadSfzFile(const fs::path& file)
|
||||||
{
|
{
|
||||||
clear();
|
|
||||||
|
|
||||||
const std::lock_guard<SpinMutex> disableCallback { callbackGuard };
|
const std::lock_guard<SpinMutex> disableCallback { callbackGuard };
|
||||||
|
|
||||||
|
clear();
|
||||||
|
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
fs::path realFile = fs::canonical(file, ec);
|
fs::path realFile = fs::canonical(file, ec);
|
||||||
|
|
||||||
|
|
@ -491,9 +492,10 @@ bool sfz::Synth::loadSfzFile(const fs::path& file)
|
||||||
|
|
||||||
bool sfz::Synth::loadSfzString(const fs::path& path, absl::string_view text)
|
bool sfz::Synth::loadSfzString(const fs::path& path, absl::string_view text)
|
||||||
{
|
{
|
||||||
|
const std::lock_guard<SpinMutex> disableCallback { callbackGuard };
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
const std::lock_guard<SpinMutex> disableCallback { callbackGuard };
|
|
||||||
parser.parseString(path, text);
|
parser.parseString(path, text);
|
||||||
if (parser.getErrorCount() > 0)
|
if (parser.getErrorCount() > 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -514,7 +516,7 @@ void sfz::Synth::finalizeSfzLoad()
|
||||||
size_t currentRegionCount = regions.size();
|
size_t currentRegionCount = regions.size();
|
||||||
|
|
||||||
auto removeCurrentRegion = [this, ¤tRegionIndex, ¤tRegionCount]() {
|
auto removeCurrentRegion = [this, ¤tRegionIndex, ¤tRegionCount]() {
|
||||||
DBG("Removing the region with sample " << regions[currentRegionIndex]->sampleId);
|
DBG("Removing the region with sample " << *regions[currentRegionIndex]->sampleId);
|
||||||
regions.erase(regions.begin() + currentRegionIndex);
|
regions.erase(regions.begin() + currentRegionIndex);
|
||||||
--currentRegionCount;
|
--currentRegionCount;
|
||||||
};
|
};
|
||||||
|
|
@ -534,12 +536,12 @@ void sfz::Synth::finalizeSfzLoad()
|
||||||
absl::optional<FileInformation> fileInformation;
|
absl::optional<FileInformation> fileInformation;
|
||||||
|
|
||||||
if (!region->isGenerator()) {
|
if (!region->isGenerator()) {
|
||||||
if (!resources.filePool.checkSampleId(region->sampleId)) {
|
if (!resources.filePool.checkSampleId(*region->sampleId)) {
|
||||||
removeCurrentRegion();
|
removeCurrentRegion();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
fileInformation = resources.filePool.getFileInformation(region->sampleId);
|
fileInformation = resources.filePool.getFileInformation(*region->sampleId);
|
||||||
if (!fileInformation) {
|
if (!fileInformation) {
|
||||||
removeCurrentRegion();
|
removeCurrentRegion();
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -583,11 +585,11 @@ void sfz::Synth::finalizeSfzLoad()
|
||||||
return Default::offsetCCRange.clamp(sumOffsetCC);
|
return Default::offsetCCRange.clamp(sumOffsetCC);
|
||||||
}();
|
}();
|
||||||
|
|
||||||
if (!resources.filePool.preloadFile(region->sampleId, maxOffset))
|
if (!resources.filePool.preloadFile(*region->sampleId, maxOffset))
|
||||||
removeCurrentRegion();
|
removeCurrentRegion();
|
||||||
}
|
}
|
||||||
else if (!region->isGenerator()) {
|
else if (!region->isGenerator()) {
|
||||||
if (!resources.wavePool.createFileWave(resources.filePool, std::string(region->sampleId.filename()))) {
|
if (!resources.wavePool.createFileWave(resources.filePool, std::string(region->sampleId->filename()))) {
|
||||||
removeCurrentRegion();
|
removeCurrentRegion();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -683,6 +683,7 @@ private:
|
||||||
* @brief Remove all regions, resets all voices and clears everything
|
* @brief Remove all regions, resets all voices and clears everything
|
||||||
* to bring back the synth in its original state.
|
* to bring back the synth in its original state.
|
||||||
*
|
*
|
||||||
|
* The callback mutex should be taken to call this function.
|
||||||
*/
|
*/
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,9 @@ void sfz::Voice::startVoice(Region* region, int delay, const TriggerEvent& event
|
||||||
if (region->isOscillator()) {
|
if (region->isOscillator()) {
|
||||||
const WavetableMulti* wave = nullptr;
|
const WavetableMulti* wave = nullptr;
|
||||||
if (!region->isGenerator())
|
if (!region->isGenerator())
|
||||||
wave = resources.wavePool.getFileWave(region->sampleId.filename());
|
wave = resources.wavePool.getFileWave(region->sampleId->filename());
|
||||||
else {
|
else {
|
||||||
switch (hash(region->sampleId.filename())) {
|
switch (hash(region->sampleId->filename())) {
|
||||||
default:
|
default:
|
||||||
case hash("*silence"):
|
case hash("*silence"):
|
||||||
break;
|
break;
|
||||||
|
|
@ -658,7 +658,7 @@ void sfz::Voice::fillWithData(AudioSpan<float> buffer) noexcept
|
||||||
DBG("[sfizz] Underflow: source available samples "
|
DBG("[sfizz] Underflow: source available samples "
|
||||||
<< source.getNumFrames() << "/"
|
<< source.getNumFrames() << "/"
|
||||||
<< currentPromise->information.end
|
<< currentPromise->information.end
|
||||||
<< " for sample " << region->sampleId);
|
<< " for sample " << *region->sampleId);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!region->flexAmpEG) {
|
if (!region->flexAmpEG) {
|
||||||
|
|
@ -891,13 +891,13 @@ void sfz::Voice::fillWithGenerator(AudioSpan<float> buffer) noexcept
|
||||||
const auto leftSpan = buffer.getSpan(0);
|
const auto leftSpan = buffer.getSpan(0);
|
||||||
const auto rightSpan = buffer.getSpan(1);
|
const auto rightSpan = buffer.getSpan(1);
|
||||||
|
|
||||||
if (region->sampleId.filename() == "*noise") {
|
if (region->sampleId->filename() == "*noise") {
|
||||||
auto gen = [&]() {
|
auto gen = [&]() {
|
||||||
return uniformNoiseDist(Random::randomGenerator);
|
return uniformNoiseDist(Random::randomGenerator);
|
||||||
};
|
};
|
||||||
absl::c_generate(leftSpan, gen);
|
absl::c_generate(leftSpan, gen);
|
||||||
absl::c_generate(rightSpan, gen);
|
absl::c_generate(rightSpan, gen);
|
||||||
} else if (region->sampleId.filename() == "*gnoise") {
|
} else if (region->sampleId->filename() == "*gnoise") {
|
||||||
// You need to wrap in a lambda, otherwise generate will
|
// You need to wrap in a lambda, otherwise generate will
|
||||||
// make a copy of the gaussian distribution *along with its state*
|
// make a copy of the gaussian distribution *along with its state*
|
||||||
// leading to periodic behavior....
|
// leading to periodic behavior....
|
||||||
|
|
@ -1092,10 +1092,11 @@ void sfz::Voice::updateLoopInformation() noexcept
|
||||||
if (!region->shouldLoop())
|
if (!region->shouldLoop())
|
||||||
return;
|
return;
|
||||||
const auto& info = currentPromise->information;
|
const auto& info = currentPromise->information;
|
||||||
|
const auto factor = resources.filePool.getOversamplingFactor();
|
||||||
const auto rate = info.sampleRate;
|
const auto rate = info.sampleRate;
|
||||||
|
|
||||||
loop.end = static_cast<int>(info.loopEnd);
|
loop.end = static_cast<int>(region->loopEnd(factor));
|
||||||
loop.start = static_cast<int>(info.loopBegin);
|
loop.start = static_cast<int>(region->loopStart(factor));
|
||||||
loop.size = loop.end + 1 - loop.start;
|
loop.size = loop.end + 1 - loop.start;
|
||||||
loop.xfSize = static_cast<int>(lroundPositive(region->loopCrossfade * rate));
|
loop.xfSize = static_cast<int>(lroundPositive(region->loopCrossfade * rate));
|
||||||
loop.xfOutStart = loop.end + 1 - loop.xfSize;
|
loop.xfOutStart = loop.end + 1 - loop.xfSize;
|
||||||
|
|
|
||||||
|
|
@ -21,55 +21,55 @@ sfizz_synth_t* sfizz_create_synth()
|
||||||
|
|
||||||
bool sfizz_load_file(sfizz_synth_t* synth, const char* path)
|
bool sfizz_load_file(sfizz_synth_t* synth, const char* path)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->loadSfzFile(path);
|
return self->loadSfzFile(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sfizz_load_string(sfizz_synth_t* synth, const char* path, const char* text)
|
bool sfizz_load_string(sfizz_synth_t* synth, const char* path, const char* text)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->loadSfzString(path, text);
|
return self->loadSfzString(path, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sfizz_load_scala_file(sfizz_synth_t* synth, const char* path)
|
bool sfizz_load_scala_file(sfizz_synth_t* synth, const char* path)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->loadScalaFile(path);
|
return self->loadScalaFile(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sfizz_load_scala_string(sfizz_synth_t* synth, const char* text)
|
bool sfizz_load_scala_string(sfizz_synth_t* synth, const char* text)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->loadScalaString(text);
|
return self->loadScalaString(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfizz_set_scala_root_key(sfizz_synth_t* synth, int root_key)
|
void sfizz_set_scala_root_key(sfizz_synth_t* synth, int root_key)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->setScalaRootKey(root_key);
|
self->setScalaRootKey(root_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sfizz_get_scala_root_key(sfizz_synth_t* synth)
|
int sfizz_get_scala_root_key(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->getScalaRootKey();
|
return self->getScalaRootKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfizz_set_tuning_frequency(sfizz_synth_t* synth, float frequency)
|
void sfizz_set_tuning_frequency(sfizz_synth_t* synth, float frequency)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->setTuningFrequency(frequency);
|
self->setTuningFrequency(frequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
float sfizz_get_tuning_frequency(sfizz_synth_t* synth)
|
float sfizz_get_tuning_frequency(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->getTuningFrequency();
|
return self->getTuningFrequency();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfizz_load_stretch_tuning_by_ratio(sfizz_synth_t* synth, float ratio)
|
void sfizz_load_stretch_tuning_by_ratio(sfizz_synth_t* synth, float ratio)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->loadStretchTuningByRatio(ratio);
|
self->loadStretchTuningByRatio(ratio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,105 +80,105 @@ void sfizz_free(sfizz_synth_t* synth)
|
||||||
|
|
||||||
int sfizz_get_num_regions(sfizz_synth_t* synth)
|
int sfizz_get_num_regions(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->getNumRegions();
|
return self->getNumRegions();
|
||||||
}
|
}
|
||||||
int sfizz_get_num_groups(sfizz_synth_t* synth)
|
int sfizz_get_num_groups(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->getNumGroups();
|
return self->getNumGroups();
|
||||||
}
|
}
|
||||||
int sfizz_get_num_masters(sfizz_synth_t* synth)
|
int sfizz_get_num_masters(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->getNumMasters();
|
return self->getNumMasters();
|
||||||
}
|
}
|
||||||
int sfizz_get_num_curves(sfizz_synth_t* synth)
|
int sfizz_get_num_curves(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->getNumCurves();
|
return self->getNumCurves();
|
||||||
}
|
}
|
||||||
char* sfizz_export_midnam(sfizz_synth_t* synth, const char* model)
|
char* sfizz_export_midnam(sfizz_synth_t* synth, const char* model)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return strdup(self->exportMidnam(model ? model : "").c_str());
|
return strdup(self->exportMidnam(model ? model : "").c_str());
|
||||||
}
|
}
|
||||||
size_t sfizz_get_num_preloaded_samples(sfizz_synth_t* synth)
|
size_t sfizz_get_num_preloaded_samples(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->getNumPreloadedSamples();
|
return self->getNumPreloadedSamples();
|
||||||
}
|
}
|
||||||
int sfizz_get_num_active_voices(sfizz_synth_t* synth)
|
int sfizz_get_num_active_voices(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->getNumActiveVoices();
|
return self->getNumActiveVoices();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfizz_set_samples_per_block(sfizz_synth_t* synth, int samples_per_block)
|
void sfizz_set_samples_per_block(sfizz_synth_t* synth, int samples_per_block)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->setSamplesPerBlock(samples_per_block);
|
self->setSamplesPerBlock(samples_per_block);
|
||||||
}
|
}
|
||||||
void sfizz_set_sample_rate(sfizz_synth_t* synth, float sample_rate)
|
void sfizz_set_sample_rate(sfizz_synth_t* synth, float sample_rate)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->setSampleRate(sample_rate);
|
self->setSampleRate(sample_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfizz_send_note_on(sfizz_synth_t* synth, int delay, int note_number, char velocity)
|
void sfizz_send_note_on(sfizz_synth_t* synth, int delay, int note_number, char velocity)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->noteOn(delay, note_number, velocity);
|
self->noteOn(delay, note_number, velocity);
|
||||||
}
|
}
|
||||||
void sfizz_send_note_off(sfizz_synth_t* synth, int delay, int note_number, char velocity)
|
void sfizz_send_note_off(sfizz_synth_t* synth, int delay, int note_number, char velocity)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->noteOff(delay, note_number, velocity);
|
self->noteOff(delay, note_number, velocity);
|
||||||
}
|
}
|
||||||
void sfizz_send_cc(sfizz_synth_t* synth, int delay, int cc_number, char cc_value)
|
void sfizz_send_cc(sfizz_synth_t* synth, int delay, int cc_number, char cc_value)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->cc(delay, cc_number, cc_value);
|
self->cc(delay, cc_number, cc_value);
|
||||||
}
|
}
|
||||||
void sfizz_send_hdcc(sfizz_synth_t* synth, int delay, int cc_number, float norm_value)
|
void sfizz_send_hdcc(sfizz_synth_t* synth, int delay, int cc_number, float norm_value)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->hdcc(delay, cc_number, norm_value);
|
self->hdcc(delay, cc_number, norm_value);
|
||||||
}
|
}
|
||||||
void sfizz_send_pitch_wheel(sfizz_synth_t* synth, int delay, int pitch)
|
void sfizz_send_pitch_wheel(sfizz_synth_t* synth, int delay, int pitch)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->pitchWheel(delay, pitch);
|
self->pitchWheel(delay, pitch);
|
||||||
}
|
}
|
||||||
void sfizz_send_aftertouch(sfizz_synth_t* synth, int delay, char aftertouch)
|
void sfizz_send_aftertouch(sfizz_synth_t* synth, int delay, char aftertouch)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->aftertouch(delay, aftertouch);
|
self->aftertouch(delay, aftertouch);
|
||||||
}
|
}
|
||||||
void sfizz_send_tempo(sfizz_synth_t* synth, int delay, float seconds_per_quarter)
|
void sfizz_send_tempo(sfizz_synth_t* synth, int delay, float seconds_per_quarter)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->tempo(delay, seconds_per_quarter);
|
self->tempo(delay, seconds_per_quarter);
|
||||||
}
|
}
|
||||||
void sfizz_send_time_signature(sfizz_synth_t* synth, int delay, int beats_per_bar, int beat_unit)
|
void sfizz_send_time_signature(sfizz_synth_t* synth, int delay, int beats_per_bar, int beat_unit)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->timeSignature(delay, beats_per_bar, beat_unit);
|
self->timeSignature(delay, beats_per_bar, beat_unit);
|
||||||
}
|
}
|
||||||
void sfizz_send_time_position(sfizz_synth_t* synth, int delay, int bar, float bar_beat)
|
void sfizz_send_time_position(sfizz_synth_t* synth, int delay, int bar, float bar_beat)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->timePosition(delay, bar, bar_beat);
|
self->timePosition(delay, bar, bar_beat);
|
||||||
}
|
}
|
||||||
void sfizz_send_playback_state(sfizz_synth_t* synth, int delay, int playback_state)
|
void sfizz_send_playback_state(sfizz_synth_t* synth, int delay, int playback_state)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->playbackState(delay, playback_state);
|
self->playbackState(delay, playback_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfizz_render_block(sfizz_synth_t* synth, float** channels, int num_channels, int num_frames)
|
void sfizz_render_block(sfizz_synth_t* synth, float** channels, int num_channels, int num_frames)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
// Only stereo output is supported for now
|
// Only stereo output is supported for now
|
||||||
ASSERT(num_channels == 2);
|
ASSERT(num_channels == 2);
|
||||||
UNUSED(num_channels);
|
UNUSED(num_channels);
|
||||||
|
|
@ -187,24 +187,24 @@ void sfizz_render_block(sfizz_synth_t* synth, float** channels, int num_channels
|
||||||
|
|
||||||
unsigned int sfizz_get_preload_size(sfizz_synth_t* synth)
|
unsigned int sfizz_get_preload_size(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->getPreloadSize();
|
return self->getPreloadSize();
|
||||||
}
|
}
|
||||||
void sfizz_set_preload_size(sfizz_synth_t* synth, unsigned int preload_size)
|
void sfizz_set_preload_size(sfizz_synth_t* synth, unsigned int preload_size)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->setPreloadSize(preload_size);
|
self->setPreloadSize(preload_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
sfizz_oversampling_factor_t sfizz_get_oversampling_factor(sfizz_synth_t* synth)
|
sfizz_oversampling_factor_t sfizz_get_oversampling_factor(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return static_cast<sfizz_oversampling_factor_t>(self->getOversamplingFactor());
|
return static_cast<sfizz_oversampling_factor_t>(self->getOversamplingFactor());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sfizz_set_oversampling_factor(sfizz_synth_t* synth, sfizz_oversampling_factor_t oversampling)
|
bool sfizz_set_oversampling_factor(sfizz_synth_t* synth, sfizz_oversampling_factor_t oversampling)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
using sfz::Oversampling;
|
using sfz::Oversampling;
|
||||||
switch(oversampling)
|
switch(oversampling)
|
||||||
{
|
{
|
||||||
|
|
@ -227,67 +227,67 @@ bool sfizz_set_oversampling_factor(sfizz_synth_t* synth, sfizz_oversampling_fact
|
||||||
|
|
||||||
int sfizz_get_sample_quality(sfizz_synth_t* synth, sfizz_process_mode_t mode)
|
int sfizz_get_sample_quality(sfizz_synth_t* synth, sfizz_process_mode_t mode)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->getSampleQuality(static_cast<sfz::Synth::ProcessMode>(mode));
|
return self->getSampleQuality(static_cast<sfz::Synth::ProcessMode>(mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfizz_set_sample_quality(sfizz_synth_t* synth, sfizz_process_mode_t mode, int quality)
|
void sfizz_set_sample_quality(sfizz_synth_t* synth, sfizz_process_mode_t mode, int quality)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->setSampleQuality(static_cast<sfz::Synth::ProcessMode>(mode), quality);
|
return self->setSampleQuality(static_cast<sfz::Synth::ProcessMode>(mode), quality);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfizz_set_volume(sfizz_synth_t* synth, float volume)
|
void sfizz_set_volume(sfizz_synth_t* synth, float volume)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->setVolume(volume);
|
self->setVolume(volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
float sfizz_get_volume(sfizz_synth_t* synth)
|
float sfizz_get_volume(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->getVolume();
|
return self->getVolume();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfizz_set_num_voices(sfizz_synth_t* synth, int num_voices)
|
void sfizz_set_num_voices(sfizz_synth_t* synth, int num_voices)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->setNumVoices(num_voices);
|
self->setNumVoices(num_voices);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sfizz_get_num_voices(sfizz_synth_t* synth)
|
int sfizz_get_num_voices(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->getNumVoices();
|
return self->getNumVoices();
|
||||||
}
|
}
|
||||||
|
|
||||||
int sfizz_get_num_buffers(sfizz_synth_t* synth)
|
int sfizz_get_num_buffers(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->getAllocatedBuffers();
|
return self->getAllocatedBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
int sfizz_get_num_bytes(sfizz_synth_t* synth)
|
int sfizz_get_num_bytes(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->getAllocatedBytes();
|
return self->getAllocatedBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfizz_enable_freewheeling(sfizz_synth_t* synth)
|
void sfizz_enable_freewheeling(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->enableFreeWheeling();
|
self->enableFreeWheeling();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfizz_disable_freewheeling(sfizz_synth_t* synth)
|
void sfizz_disable_freewheeling(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->disableFreeWheeling();
|
self->disableFreeWheeling();
|
||||||
}
|
}
|
||||||
|
|
||||||
char* sfizz_get_unknown_opcodes(sfizz_synth_t* synth)
|
char* sfizz_get_unknown_opcodes(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
const auto unknownOpcodes = self->getUnknownOpcodes();
|
const auto unknownOpcodes = self->getUnknownOpcodes();
|
||||||
size_t totalLength = 0;
|
size_t totalLength = 0;
|
||||||
for (auto& opcode: unknownOpcodes)
|
for (auto& opcode: unknownOpcodes)
|
||||||
|
|
@ -309,61 +309,61 @@ char* sfizz_get_unknown_opcodes(sfizz_synth_t* synth)
|
||||||
|
|
||||||
bool sfizz_should_reload_file(sfizz_synth_t* synth)
|
bool sfizz_should_reload_file(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->shouldReloadFile();
|
return self->shouldReloadFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sfizz_should_reload_scala(sfizz_synth_t* synth)
|
bool sfizz_should_reload_scala(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->shouldReloadScala();
|
return self->shouldReloadScala();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfizz_enable_logging(sfizz_synth_t* synth)
|
void sfizz_enable_logging(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->enableLogging();
|
return self->enableLogging();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfizz_set_logging_prefix(sfizz_synth_t* synth, const char* prefix)
|
void sfizz_set_logging_prefix(sfizz_synth_t* synth, const char* prefix)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->setLoggingPrefix(prefix);
|
return self->setLoggingPrefix(prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfizz_disable_logging(sfizz_synth_t* synth)
|
void sfizz_disable_logging(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->disableLogging();
|
return self->disableLogging();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfizz_all_sound_off(sfizz_synth_t* synth)
|
void sfizz_all_sound_off(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->allSoundOff();
|
return self->allSoundOff();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfizz_add_external_definitions(sfizz_synth_t* synth, const char* id, const char* value)
|
void sfizz_add_external_definitions(sfizz_synth_t* synth, const char* id, const char* value)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->getParser().addExternalDefinition(id, value);
|
self->getParser().addExternalDefinition(id, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfizz_clear_external_definitions(sfizz_synth_t* synth)
|
void sfizz_clear_external_definitions(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->getParser().clearExternalDefinitions();
|
self->getParser().clearExternalDefinitions();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int sfizz_get_num_key_labels(sfizz_synth_t* synth)
|
unsigned int sfizz_get_num_key_labels(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->getKeyLabels().size();
|
return self->getKeyLabels().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int sfizz_get_key_label_number(sfizz_synth_t* synth, int label_index)
|
int sfizz_get_key_label_number(sfizz_synth_t* synth, int label_index)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
const auto keyLabels = self->getKeyLabels();
|
const auto keyLabels = self->getKeyLabels();
|
||||||
if (label_index < 0)
|
if (label_index < 0)
|
||||||
return SFIZZ_OUT_OF_BOUNDS_LABEL_INDEX;
|
return SFIZZ_OUT_OF_BOUNDS_LABEL_INDEX;
|
||||||
|
|
@ -381,7 +381,7 @@ int sfizz_get_key_label_number(sfizz_synth_t* synth, int label_index)
|
||||||
|
|
||||||
const char * sfizz_get_key_label_text(sfizz_synth_t* synth, int label_index)
|
const char * sfizz_get_key_label_text(sfizz_synth_t* synth, int label_index)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
const auto keyLabels = self->getKeyLabels();
|
const auto keyLabels = self->getKeyLabels();
|
||||||
if (label_index < 0)
|
if (label_index < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -394,13 +394,13 @@ const char * sfizz_get_key_label_text(sfizz_synth_t* synth, int label_index)
|
||||||
|
|
||||||
unsigned int sfizz_get_num_cc_labels(sfizz_synth_t* synth)
|
unsigned int sfizz_get_num_cc_labels(sfizz_synth_t* synth)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
return self->getCCLabels().size();
|
return self->getCCLabels().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int sfizz_get_cc_label_number(sfizz_synth_t* synth, int label_index)
|
int sfizz_get_cc_label_number(sfizz_synth_t* synth, int label_index)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
const auto ccLabels = self->getCCLabels();
|
const auto ccLabels = self->getCCLabels();
|
||||||
if (label_index < 0)
|
if (label_index < 0)
|
||||||
return SFIZZ_OUT_OF_BOUNDS_LABEL_INDEX;
|
return SFIZZ_OUT_OF_BOUNDS_LABEL_INDEX;
|
||||||
|
|
@ -418,7 +418,7 @@ int sfizz_get_cc_label_number(sfizz_synth_t* synth, int label_index)
|
||||||
|
|
||||||
const char * sfizz_get_cc_label_text(sfizz_synth_t* synth, int label_index)
|
const char * sfizz_get_cc_label_text(sfizz_synth_t* synth, int label_index)
|
||||||
{
|
{
|
||||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
const auto ccLabels = self->getCCLabels();
|
const auto ccLabels = self->getCCLabels();
|
||||||
if (label_index < 0)
|
if (label_index < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ constexpr unsigned ByteAlignment = TypeAlignment * sizeof(Type);
|
||||||
|
|
||||||
void gain1AVX(float gain, const float* input, float* output, unsigned size) noexcept
|
void gain1AVX(float gain, const float* input, float* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_AVX
|
#if SFIZZ_HAVE_AVX
|
||||||
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
||||||
|
|
@ -38,7 +38,7 @@ void gain1AVX(float gain, const float* input, float* output, unsigned size) noex
|
||||||
|
|
||||||
void gainAVX(const float* gain, const float* input, float* output, unsigned size) noexcept
|
void gainAVX(const float* gain, const float* input, float* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_AVX
|
#if SFIZZ_HAVE_AVX
|
||||||
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ constexpr unsigned ByteAlignment = TypeAlignment * sizeof(Type);
|
||||||
|
|
||||||
void readInterleavedSSE(const float* input, float* outputLeft, float* outputRight, unsigned inputSize) noexcept
|
void readInterleavedSSE(const float* input, float* outputLeft, float* outputRight, unsigned inputSize) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = input + inputSize - 1;
|
const auto* sentinel = input + inputSize - 1;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
const auto* lastAligned = prevAligned<ByteAlignment>(input + inputSize - TypeAlignment);
|
const auto* lastAligned = prevAligned<ByteAlignment>(input + inputSize - TypeAlignment);
|
||||||
|
|
@ -56,7 +56,7 @@ void readInterleavedSSE(const float* input, float* outputLeft, float* outputRigh
|
||||||
|
|
||||||
void writeInterleavedSSE(const float* inputLeft, const float* inputRight, float* output, unsigned outputSize) noexcept
|
void writeInterleavedSSE(const float* inputLeft, const float* inputRight, float* output, unsigned outputSize) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + outputSize - 1;
|
const auto* sentinel = output + outputSize - 1;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
const auto* lastAligned = prevAligned<ByteAlignment>(output + outputSize - TypeAlignment);
|
const auto* lastAligned = prevAligned<ByteAlignment>(output + outputSize - TypeAlignment);
|
||||||
|
|
@ -84,7 +84,7 @@ void writeInterleavedSSE(const float* inputLeft, const float* inputRight, float*
|
||||||
|
|
||||||
void gain1SSE(float gain, const float* input, float* output, unsigned size) noexcept
|
void gain1SSE(float gain, const float* input, float* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
||||||
|
|
@ -104,7 +104,7 @@ void gain1SSE(float gain, const float* input, float* output, unsigned size) noex
|
||||||
|
|
||||||
void gainSSE(const float* gain, const float* input, float* output, unsigned size) noexcept
|
void gainSSE(const float* gain, const float* input, float* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
||||||
|
|
@ -123,7 +123,7 @@ void gainSSE(const float* gain, const float* input, float* output, unsigned size
|
||||||
|
|
||||||
void divideSSE(const float* input, const float* divisor, float* output, unsigned size) noexcept
|
void divideSSE(const float* input, const float* divisor, float* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
||||||
|
|
@ -142,7 +142,7 @@ void divideSSE(const float* input, const float* divisor, float* output, unsigned
|
||||||
|
|
||||||
void multiplyAddSSE(const float* gain, const float* input, float* output, unsigned size) noexcept
|
void multiplyAddSSE(const float* gain, const float* input, float* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
||||||
|
|
@ -163,7 +163,7 @@ void multiplyAddSSE(const float* gain, const float* input, float* output, unsign
|
||||||
|
|
||||||
void multiplyAdd1SSE(float gain, const float* input, float* output, unsigned size) noexcept
|
void multiplyAdd1SSE(float gain, const float* input, float* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
||||||
|
|
@ -185,7 +185,7 @@ void multiplyAdd1SSE(float gain, const float* input, float* output, unsigned siz
|
||||||
|
|
||||||
void multiplyMulSSE(const float* gain, const float* input, float* output, unsigned size) noexcept
|
void multiplyMulSSE(const float* gain, const float* input, float* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
||||||
|
|
@ -206,7 +206,7 @@ void multiplyMulSSE(const float* gain, const float* input, float* output, unsign
|
||||||
|
|
||||||
void multiplyMul1SSE(float gain, const float* input, float* output, unsigned size) noexcept
|
void multiplyMul1SSE(float gain, const float* input, float* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
||||||
|
|
@ -228,7 +228,7 @@ void multiplyMul1SSE(float gain, const float* input, float* output, unsigned siz
|
||||||
|
|
||||||
float linearRampSSE(float* output, float start, float step, unsigned size) noexcept
|
float linearRampSSE(float* output, float start, float step, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
||||||
|
|
@ -257,7 +257,7 @@ float linearRampSSE(float* output, float start, float step, unsigned size) noexc
|
||||||
|
|
||||||
float multiplicativeRampSSE(float* output, float start, float step, unsigned size) noexcept
|
float multiplicativeRampSSE(float* output, float start, float step, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
||||||
|
|
@ -286,7 +286,7 @@ float multiplicativeRampSSE(float* output, float start, float step, unsigned siz
|
||||||
|
|
||||||
void addSSE(const float* input, float* output, unsigned size) noexcept
|
void addSSE(const float* input, float* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
||||||
|
|
@ -305,7 +305,7 @@ void addSSE(const float* input, float* output, unsigned size) noexcept
|
||||||
|
|
||||||
void add1SSE(float value, float* output, unsigned size) noexcept
|
void add1SSE(float value, float* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
||||||
|
|
@ -325,7 +325,7 @@ void add1SSE(float value, float* output, unsigned size) noexcept
|
||||||
|
|
||||||
void subtractSSE(const float* input, float* output, unsigned size) noexcept
|
void subtractSSE(const float* input, float* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
||||||
|
|
@ -344,7 +344,7 @@ void subtractSSE(const float* input, float* output, unsigned size) noexcept
|
||||||
|
|
||||||
void subtract1SSE(float value, float* output, unsigned size) noexcept
|
void subtract1SSE(float value, float* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
||||||
|
|
@ -365,7 +365,7 @@ void subtract1SSE(float value, float* output, unsigned size) noexcept
|
||||||
void copySSE(const float* input, float* output, unsigned size) noexcept
|
void copySSE(const float* input, float* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
// The sentinel is the input here
|
// The sentinel is the input here
|
||||||
const auto sentinel = input + size;
|
const auto* sentinel = input + size;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
||||||
|
|
@ -383,7 +383,7 @@ void copySSE(const float* input, float* output, unsigned size) noexcept
|
||||||
|
|
||||||
float meanSSE(const float* vector, unsigned size) noexcept
|
float meanSSE(const float* vector, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = vector + size;
|
const auto* sentinel = vector + size;
|
||||||
|
|
||||||
float result { 0.0f };
|
float result { 0.0f };
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
|
|
@ -415,7 +415,7 @@ float meanSSE(const float* vector, unsigned size) noexcept
|
||||||
|
|
||||||
float sumSquaresSSE(const float* vector, unsigned size) noexcept
|
float sumSquaresSSE(const float* vector, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = vector + size;
|
const auto* sentinel = vector + size;
|
||||||
|
|
||||||
float result { 0.0f };
|
float result { 0.0f };
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
|
|
@ -455,7 +455,7 @@ void cumsumSSE(const float* input, float* output, unsigned size) noexcept
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
*output++ = *input++;
|
*output++ = *input++;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
|
|
@ -488,7 +488,7 @@ void diffSSE(const float* input, float* output, unsigned size) noexcept
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
*output++ = *input++;
|
*output++ = *input++;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
|
|
@ -521,7 +521,7 @@ void clampAllSSE(float* input, float low, float high, unsigned size) noexcept
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto sentinel = input + size;
|
const auto* sentinel = input + size;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
||||||
|
|
@ -555,7 +555,7 @@ bool allWithinSSE(const float* input, float low, float high, unsigned size) noex
|
||||||
if (low > high)
|
if (low > high)
|
||||||
std::swap(low, high);
|
std::swap(low, high);
|
||||||
|
|
||||||
const auto sentinel = input + size;
|
const auto* sentinel = input + size;
|
||||||
|
|
||||||
#if SFIZZ_HAVE_SSE2
|
#if SFIZZ_HAVE_SSE2
|
||||||
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
const auto* lastAligned = prevAligned<ByteAlignment>(sentinel);
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
template<class T>
|
template<class T>
|
||||||
inline void readInterleavedScalar(const T* input, T* outputLeft, T* outputRight, unsigned inputSize) noexcept
|
inline void readInterleavedScalar(const T* input, T* outputLeft, T* outputRight, unsigned inputSize) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = input + inputSize - 1;
|
const auto* sentinel = input + inputSize - 1;
|
||||||
while (input < sentinel) {
|
while (input < sentinel) {
|
||||||
*outputLeft++ = *input++;
|
*outputLeft++ = *input++;
|
||||||
*outputRight++ = *input++;
|
*outputRight++ = *input++;
|
||||||
|
|
@ -20,7 +20,7 @@ inline void readInterleavedScalar(const T* input, T* outputLeft, T* outputRight,
|
||||||
template<class T>
|
template<class T>
|
||||||
inline void writeInterleavedScalar(const T* inputLeft, const T* inputRight, T* output, unsigned outputSize) noexcept
|
inline void writeInterleavedScalar(const T* inputLeft, const T* inputRight, T* output, unsigned outputSize) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + outputSize - 1;
|
const auto* sentinel = output + outputSize - 1;
|
||||||
while (output < sentinel) {
|
while (output < sentinel) {
|
||||||
*output++ = *inputLeft++;
|
*output++ = *inputLeft++;
|
||||||
*output++ = *inputRight++;
|
*output++ = *inputRight++;
|
||||||
|
|
@ -30,7 +30,7 @@ inline void writeInterleavedScalar(const T* inputLeft, const T* inputRight, T* o
|
||||||
template<class T>
|
template<class T>
|
||||||
inline void gain1Scalar(T gain, const T* input, T* output, unsigned size) noexcept
|
inline void gain1Scalar(T gain, const T* input, T* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
while (output < sentinel)
|
while (output < sentinel)
|
||||||
*output++ = gain * (*input++);
|
*output++ = gain * (*input++);
|
||||||
}
|
}
|
||||||
|
|
@ -38,7 +38,7 @@ inline void gain1Scalar(T gain, const T* input, T* output, unsigned size) noexce
|
||||||
template<class T>
|
template<class T>
|
||||||
inline void gainScalar(const T* gain, const T* input, T* output, unsigned size) noexcept
|
inline void gainScalar(const T* gain, const T* input, T* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
while (output < sentinel)
|
while (output < sentinel)
|
||||||
*output++ = (*gain++) * (*input++);
|
*output++ = (*gain++) * (*input++);
|
||||||
}
|
}
|
||||||
|
|
@ -46,7 +46,7 @@ inline void gainScalar(const T* gain, const T* input, T* output, unsigned size)
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void divideScalar(const T* input, const T* divisor, T* output, unsigned size) noexcept
|
inline void divideScalar(const T* input, const T* divisor, T* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
while (output < sentinel)
|
while (output < sentinel)
|
||||||
*output++ = (*input++) / (*divisor++);
|
*output++ = (*input++) / (*divisor++);
|
||||||
}
|
}
|
||||||
|
|
@ -54,7 +54,7 @@ inline void divideScalar(const T* input, const T* divisor, T* output, unsigned s
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void multiplyAddScalar(const T* gain, const T* input, T* output, unsigned size) noexcept
|
inline void multiplyAddScalar(const T* gain, const T* input, T* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
while (output < sentinel)
|
while (output < sentinel)
|
||||||
*output++ += (*gain++) * (*input++);
|
*output++ += (*gain++) * (*input++);
|
||||||
}
|
}
|
||||||
|
|
@ -62,7 +62,7 @@ inline void multiplyAddScalar(const T* gain, const T* input, T* output, unsigned
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void multiplyAdd1Scalar(T gain, const T* input, T* output, unsigned size) noexcept
|
inline void multiplyAdd1Scalar(T gain, const T* input, T* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
while (output < sentinel)
|
while (output < sentinel)
|
||||||
*output++ += gain * (*input++);
|
*output++ += gain * (*input++);
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +70,7 @@ inline void multiplyAdd1Scalar(T gain, const T* input, T* output, unsigned size)
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void multiplyMulScalar(const T* gain, const T* input, T* output, unsigned size) noexcept
|
inline void multiplyMulScalar(const T* gain, const T* input, T* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
while (output < sentinel)
|
while (output < sentinel)
|
||||||
*output++ *= (*gain++) * (*input++);
|
*output++ *= (*gain++) * (*input++);
|
||||||
}
|
}
|
||||||
|
|
@ -78,7 +78,7 @@ inline void multiplyMulScalar(const T* gain, const T* input, T* output, unsigned
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void multiplyMul1Scalar(T gain, const T* input, T* output, unsigned size) noexcept
|
inline void multiplyMul1Scalar(T gain, const T* input, T* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
while (output < sentinel)
|
while (output < sentinel)
|
||||||
*output++ *= gain * (*input++);
|
*output++ *= gain * (*input++);
|
||||||
}
|
}
|
||||||
|
|
@ -86,7 +86,7 @@ inline void multiplyMul1Scalar(T gain, const T* input, T* output, unsigned size)
|
||||||
template <class T>
|
template <class T>
|
||||||
T linearRampScalar(T* output, T start, T step, unsigned size) noexcept
|
T linearRampScalar(T* output, T start, T step, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
while (output < sentinel) {
|
while (output < sentinel) {
|
||||||
*output++ = start;
|
*output++ = start;
|
||||||
start += step;
|
start += step;
|
||||||
|
|
@ -97,7 +97,7 @@ T linearRampScalar(T* output, T start, T step, unsigned size) noexcept
|
||||||
template <class T>
|
template <class T>
|
||||||
T multiplicativeRampScalar(T* output, T start, T step, unsigned size) noexcept
|
T multiplicativeRampScalar(T* output, T start, T step, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
while (output < sentinel) {
|
while (output < sentinel) {
|
||||||
*output++ = start;
|
*output++ = start;
|
||||||
start *= step;
|
start *= step;
|
||||||
|
|
@ -108,7 +108,7 @@ T multiplicativeRampScalar(T* output, T start, T step, unsigned size) noexcept
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void addScalar(const T* input, T* output, unsigned size) noexcept
|
inline void addScalar(const T* input, T* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
while (output < sentinel)
|
while (output < sentinel)
|
||||||
*output++ += *input++;
|
*output++ += *input++;
|
||||||
}
|
}
|
||||||
|
|
@ -116,7 +116,7 @@ inline void addScalar(const T* input, T* output, unsigned size) noexcept
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void add1Scalar(T value, T* output, unsigned size) noexcept
|
inline void add1Scalar(T value, T* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
while (output < sentinel)
|
while (output < sentinel)
|
||||||
*output++ += value;
|
*output++ += value;
|
||||||
}
|
}
|
||||||
|
|
@ -124,7 +124,7 @@ inline void add1Scalar(T value, T* output, unsigned size) noexcept
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void subtractScalar(const T* input, T* output, unsigned size) noexcept
|
inline void subtractScalar(const T* input, T* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
while (output < sentinel)
|
while (output < sentinel)
|
||||||
*output++ -= *input++;
|
*output++ -= *input++;
|
||||||
}
|
}
|
||||||
|
|
@ -132,7 +132,7 @@ inline void subtractScalar(const T* input, T* output, unsigned size) noexcept
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void subtract1Scalar(T value, T* output, unsigned size) noexcept
|
inline void subtract1Scalar(T value, T* output, unsigned size) noexcept
|
||||||
{
|
{
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
while (output < sentinel)
|
while (output < sentinel)
|
||||||
*output++ -= value;
|
*output++ -= value;
|
||||||
}
|
}
|
||||||
|
|
@ -150,7 +150,7 @@ T meanScalar(const T* vector, unsigned size) noexcept
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
const auto sentinel = vector + size;
|
const auto* sentinel = vector + size;
|
||||||
while (vector < sentinel)
|
while (vector < sentinel)
|
||||||
result += *vector++;
|
result += *vector++;
|
||||||
|
|
||||||
|
|
@ -164,7 +164,7 @@ T sumSquaresScalar(const T* vector, unsigned size) noexcept
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
const auto sentinel = vector + size;
|
const auto* sentinel = vector + size;
|
||||||
while (vector < sentinel) {
|
while (vector < sentinel) {
|
||||||
result += (*vector) * (*vector);
|
result += (*vector) * (*vector);
|
||||||
vector++;
|
vector++;
|
||||||
|
|
@ -179,7 +179,7 @@ void cumsumScalar(const T* input, T* output, unsigned size) noexcept
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
|
|
||||||
*output++ = *input++;
|
*output++ = *input++;
|
||||||
while (output < sentinel) {
|
while (output < sentinel) {
|
||||||
|
|
@ -194,7 +194,7 @@ void diffScalar(const T* input, T* output, unsigned size) noexcept
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto sentinel = output + size;
|
const auto* sentinel = output + size;
|
||||||
|
|
||||||
*output++ = *input++;
|
*output++ = *input++;
|
||||||
while (output < sentinel) {
|
while (output < sentinel) {
|
||||||
|
|
@ -209,7 +209,7 @@ void clampAllScalar(T* input, T low, T high, unsigned size ) noexcept
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto sentinel = input + size;
|
const auto* sentinel = input + size;
|
||||||
while (input < sentinel) {
|
while (input < sentinel) {
|
||||||
const float clampedAbove = *input > high ? high : *input;
|
const float clampedAbove = *input > high ? high : *input;
|
||||||
*input = clampedAbove < low ? low : clampedAbove;
|
*input = clampedAbove < low ? low : clampedAbove;
|
||||||
|
|
@ -226,7 +226,7 @@ bool allWithinScalar(const T* input, T low, T high, unsigned size ) noexcept
|
||||||
if (low > high)
|
if (low > high)
|
||||||
std::swap(low, high);
|
std::swap(low, high);
|
||||||
|
|
||||||
const auto sentinel = input + size;
|
const auto* sentinel = input + size;
|
||||||
while (input < sentinel) {
|
while (input < sentinel) {
|
||||||
if (*input < low || *input > high)
|
if (*input < low || *input > high)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
120
tests/FilesT.cpp
120
tests/FilesT.cpp
|
|
@ -23,7 +23,7 @@ TEST_CASE("[Files] Single region (regions_one.sfz)")
|
||||||
Synth synth;
|
Synth synth;
|
||||||
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Regions/regions_one.sfz");
|
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Regions/regions_one.sfz");
|
||||||
REQUIRE(synth.getNumRegions() == 1);
|
REQUIRE(synth.getNumRegions() == 1);
|
||||||
REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy.wav");
|
REQUIRE(synth.getRegionView(0)->sampleId->filename() == "dummy.wav");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -32,9 +32,9 @@ TEST_CASE("[Files] Multiple regions (regions_many.sfz)")
|
||||||
Synth synth;
|
Synth synth;
|
||||||
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Regions/regions_many.sfz");
|
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Regions/regions_many.sfz");
|
||||||
REQUIRE(synth.getNumRegions() == 3);
|
REQUIRE(synth.getNumRegions() == 3);
|
||||||
REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy.wav");
|
REQUIRE(synth.getRegionView(0)->sampleId->filename() == "dummy.wav");
|
||||||
REQUIRE(synth.getRegionView(1)->sampleId.filename() == "dummy.1.wav");
|
REQUIRE(synth.getRegionView(1)->sampleId->filename() == "dummy.1.wav");
|
||||||
REQUIRE(synth.getRegionView(2)->sampleId.filename() == "dummy.2.wav");
|
REQUIRE(synth.getRegionView(2)->sampleId->filename() == "dummy.2.wav");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Files] Basic opcodes (regions_opcodes.sfz)")
|
TEST_CASE("[Files] Basic opcodes (regions_opcodes.sfz)")
|
||||||
|
|
@ -58,8 +58,8 @@ TEST_CASE("[Files] (regions_bad.sfz)")
|
||||||
Synth synth;
|
Synth synth;
|
||||||
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Regions/regions_bad.sfz");
|
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Regions/regions_bad.sfz");
|
||||||
REQUIRE(synth.getNumRegions() == 2);
|
REQUIRE(synth.getNumRegions() == 2);
|
||||||
REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy.wav");
|
REQUIRE(synth.getRegionView(0)->sampleId->filename() == "dummy.wav");
|
||||||
REQUIRE(synth.getRegionView(1)->sampleId.filename() == "dummy.wav");
|
REQUIRE(synth.getRegionView(1)->sampleId->filename() == "dummy.wav");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Files] Local include")
|
TEST_CASE("[Files] Local include")
|
||||||
|
|
@ -67,7 +67,7 @@ TEST_CASE("[Files] Local include")
|
||||||
Synth synth;
|
Synth synth;
|
||||||
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/root_local.sfz");
|
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/root_local.sfz");
|
||||||
REQUIRE(synth.getNumRegions() == 1);
|
REQUIRE(synth.getNumRegions() == 1);
|
||||||
REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy.wav");
|
REQUIRE(synth.getRegionView(0)->sampleId->filename() == "dummy.wav");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Files] Multiple includes")
|
TEST_CASE("[Files] Multiple includes")
|
||||||
|
|
@ -75,8 +75,8 @@ TEST_CASE("[Files] Multiple includes")
|
||||||
Synth synth;
|
Synth synth;
|
||||||
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/multiple_includes.sfz");
|
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/multiple_includes.sfz");
|
||||||
REQUIRE(synth.getNumRegions() == 2);
|
REQUIRE(synth.getNumRegions() == 2);
|
||||||
REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy.wav");
|
REQUIRE(synth.getRegionView(0)->sampleId->filename() == "dummy.wav");
|
||||||
REQUIRE(synth.getRegionView(1)->sampleId.filename() == "dummy2.wav");
|
REQUIRE(synth.getRegionView(1)->sampleId->filename() == "dummy2.wav");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Files] Multiple includes with comments")
|
TEST_CASE("[Files] Multiple includes with comments")
|
||||||
|
|
@ -84,8 +84,8 @@ TEST_CASE("[Files] Multiple includes with comments")
|
||||||
Synth synth;
|
Synth synth;
|
||||||
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/multiple_includes_with_comments.sfz");
|
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/multiple_includes_with_comments.sfz");
|
||||||
REQUIRE(synth.getNumRegions() == 2);
|
REQUIRE(synth.getNumRegions() == 2);
|
||||||
REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy.wav");
|
REQUIRE(synth.getRegionView(0)->sampleId->filename() == "dummy.wav");
|
||||||
REQUIRE(synth.getRegionView(1)->sampleId.filename() == "dummy2.wav");
|
REQUIRE(synth.getRegionView(1)->sampleId->filename() == "dummy2.wav");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Files] Subdir include")
|
TEST_CASE("[Files] Subdir include")
|
||||||
|
|
@ -93,7 +93,7 @@ TEST_CASE("[Files] Subdir include")
|
||||||
Synth synth;
|
Synth synth;
|
||||||
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/root_subdir.sfz");
|
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/root_subdir.sfz");
|
||||||
REQUIRE(synth.getNumRegions() == 1);
|
REQUIRE(synth.getNumRegions() == 1);
|
||||||
REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy_subdir.wav");
|
REQUIRE(synth.getRegionView(0)->sampleId->filename() == "dummy_subdir.wav");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Files] Subdir include Win")
|
TEST_CASE("[Files] Subdir include Win")
|
||||||
|
|
@ -101,7 +101,7 @@ TEST_CASE("[Files] Subdir include Win")
|
||||||
Synth synth;
|
Synth synth;
|
||||||
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/root_subdir_win.sfz");
|
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/root_subdir_win.sfz");
|
||||||
REQUIRE(synth.getNumRegions() == 1);
|
REQUIRE(synth.getNumRegions() == 1);
|
||||||
REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy_subdir.wav");
|
REQUIRE(synth.getRegionView(0)->sampleId->filename() == "dummy_subdir.wav");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Files] Recursive include (with include guard)")
|
TEST_CASE("[Files] Recursive include (with include guard)")
|
||||||
|
|
@ -111,8 +111,8 @@ TEST_CASE("[Files] Recursive include (with include guard)")
|
||||||
parser.setRecursiveIncludeGuardEnabled(true);
|
parser.setRecursiveIncludeGuardEnabled(true);
|
||||||
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/root_recursive.sfz");
|
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/root_recursive.sfz");
|
||||||
REQUIRE(synth.getNumRegions() == 2);
|
REQUIRE(synth.getNumRegions() == 2);
|
||||||
REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy_recursive2.wav");
|
REQUIRE(synth.getRegionView(0)->sampleId->filename() == "dummy_recursive2.wav");
|
||||||
REQUIRE(synth.getRegionView(1)->sampleId.filename() == "dummy_recursive1.wav");
|
REQUIRE(synth.getRegionView(1)->sampleId->filename() == "dummy_recursive1.wav");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Files] Include loops (with include guard)")
|
TEST_CASE("[Files] Include loops (with include guard)")
|
||||||
|
|
@ -122,8 +122,8 @@ TEST_CASE("[Files] Include loops (with include guard)")
|
||||||
parser.setRecursiveIncludeGuardEnabled(true);
|
parser.setRecursiveIncludeGuardEnabled(true);
|
||||||
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/root_loop.sfz");
|
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/Includes/root_loop.sfz");
|
||||||
REQUIRE(synth.getNumRegions() == 2);
|
REQUIRE(synth.getNumRegions() == 2);
|
||||||
REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy_loop2.wav");
|
REQUIRE(synth.getRegionView(0)->sampleId->filename() == "dummy_loop2.wav");
|
||||||
REQUIRE(synth.getRegionView(1)->sampleId.filename() == "dummy_loop1.wav");
|
REQUIRE(synth.getRegionView(1)->sampleId->filename() == "dummy_loop1.wav");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Files] Define test")
|
TEST_CASE("[Files] Define test")
|
||||||
|
|
@ -209,28 +209,28 @@ TEST_CASE("[Files] Full hierarchy with antislashes")
|
||||||
Synth synth;
|
Synth synth;
|
||||||
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/basic_hierarchy.sfz");
|
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/basic_hierarchy.sfz");
|
||||||
REQUIRE(synth.getNumRegions() == 8);
|
REQUIRE(synth.getNumRegions() == 8);
|
||||||
REQUIRE(synth.getRegionView(0)->sampleId.filename() == "Regions/dummy.wav");
|
REQUIRE(synth.getRegionView(0)->sampleId->filename() == "Regions/dummy.wav");
|
||||||
REQUIRE(synth.getRegionView(1)->sampleId.filename() == "Regions/dummy.1.wav");
|
REQUIRE(synth.getRegionView(1)->sampleId->filename() == "Regions/dummy.1.wav");
|
||||||
REQUIRE(synth.getRegionView(2)->sampleId.filename() == "Regions/dummy.wav");
|
REQUIRE(synth.getRegionView(2)->sampleId->filename() == "Regions/dummy.wav");
|
||||||
REQUIRE(synth.getRegionView(3)->sampleId.filename() == "Regions/dummy.1.wav");
|
REQUIRE(synth.getRegionView(3)->sampleId->filename() == "Regions/dummy.1.wav");
|
||||||
REQUIRE(synth.getRegionView(4)->sampleId.filename() == "Regions/dummy.wav");
|
REQUIRE(synth.getRegionView(4)->sampleId->filename() == "Regions/dummy.wav");
|
||||||
REQUIRE(synth.getRegionView(5)->sampleId.filename() == "Regions/dummy.1.wav");
|
REQUIRE(synth.getRegionView(5)->sampleId->filename() == "Regions/dummy.1.wav");
|
||||||
REQUIRE(synth.getRegionView(6)->sampleId.filename() == "Regions/dummy.wav");
|
REQUIRE(synth.getRegionView(6)->sampleId->filename() == "Regions/dummy.wav");
|
||||||
REQUIRE(synth.getRegionView(7)->sampleId.filename() == "Regions/dummy.1.wav");
|
REQUIRE(synth.getRegionView(7)->sampleId->filename() == "Regions/dummy.1.wav");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Synth synth;
|
Synth synth;
|
||||||
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/basic_hierarchy_antislash.sfz");
|
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/basic_hierarchy_antislash.sfz");
|
||||||
REQUIRE(synth.getNumRegions() == 8);
|
REQUIRE(synth.getNumRegions() == 8);
|
||||||
REQUIRE(synth.getRegionView(0)->sampleId.filename() == "Regions/dummy.wav");
|
REQUIRE(synth.getRegionView(0)->sampleId->filename() == "Regions/dummy.wav");
|
||||||
REQUIRE(synth.getRegionView(1)->sampleId.filename() == "Regions/dummy.1.wav");
|
REQUIRE(synth.getRegionView(1)->sampleId->filename() == "Regions/dummy.1.wav");
|
||||||
REQUIRE(synth.getRegionView(2)->sampleId.filename() == "Regions/dummy.wav");
|
REQUIRE(synth.getRegionView(2)->sampleId->filename() == "Regions/dummy.wav");
|
||||||
REQUIRE(synth.getRegionView(3)->sampleId.filename() == "Regions/dummy.1.wav");
|
REQUIRE(synth.getRegionView(3)->sampleId->filename() == "Regions/dummy.1.wav");
|
||||||
REQUIRE(synth.getRegionView(4)->sampleId.filename() == "Regions/dummy.wav");
|
REQUIRE(synth.getRegionView(4)->sampleId->filename() == "Regions/dummy.wav");
|
||||||
REQUIRE(synth.getRegionView(5)->sampleId.filename() == "Regions/dummy.1.wav");
|
REQUIRE(synth.getRegionView(5)->sampleId->filename() == "Regions/dummy.1.wav");
|
||||||
REQUIRE(synth.getRegionView(6)->sampleId.filename() == "Regions/dummy.wav");
|
REQUIRE(synth.getRegionView(6)->sampleId->filename() == "Regions/dummy.wav");
|
||||||
REQUIRE(synth.getRegionView(7)->sampleId.filename() == "Regions/dummy.1.wav");
|
REQUIRE(synth.getRegionView(7)->sampleId->filename() == "Regions/dummy.1.wav");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -249,10 +249,10 @@ TEST_CASE("[Files] Pizz basic")
|
||||||
REQUIRE(synth.getRegionView(1)->randRange == Range<float>(0.25, 0.5));
|
REQUIRE(synth.getRegionView(1)->randRange == Range<float>(0.25, 0.5));
|
||||||
REQUIRE(synth.getRegionView(2)->randRange == Range<float>(0.5, 0.75));
|
REQUIRE(synth.getRegionView(2)->randRange == Range<float>(0.5, 0.75));
|
||||||
REQUIRE(synth.getRegionView(3)->randRange == Range<float>(0.75, 1.0));
|
REQUIRE(synth.getRegionView(3)->randRange == Range<float>(0.75, 1.0));
|
||||||
REQUIRE(synth.getRegionView(0)->sampleId.filename() == R"(../Samples/pizz/a0_vl4_rr1.wav)");
|
REQUIRE(synth.getRegionView(0)->sampleId->filename() == R"(../Samples/pizz/a0_vl4_rr1.wav)");
|
||||||
REQUIRE(synth.getRegionView(1)->sampleId.filename() == R"(../Samples/pizz/a0_vl4_rr2.wav)");
|
REQUIRE(synth.getRegionView(1)->sampleId->filename() == R"(../Samples/pizz/a0_vl4_rr2.wav)");
|
||||||
REQUIRE(synth.getRegionView(2)->sampleId.filename() == R"(../Samples/pizz/a0_vl4_rr3.wav)");
|
REQUIRE(synth.getRegionView(2)->sampleId->filename() == R"(../Samples/pizz/a0_vl4_rr3.wav)");
|
||||||
REQUIRE(synth.getRegionView(3)->sampleId.filename() == R"(../Samples/pizz/a0_vl4_rr4.wav)");
|
REQUIRE(synth.getRegionView(3)->sampleId->filename() == R"(../Samples/pizz/a0_vl4_rr4.wav)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Files] Channels (channels.sfz)")
|
TEST_CASE("[Files] Channels (channels.sfz)")
|
||||||
|
|
@ -260,9 +260,9 @@ TEST_CASE("[Files] Channels (channels.sfz)")
|
||||||
Synth synth;
|
Synth synth;
|
||||||
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/channels.sfz");
|
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/channels.sfz");
|
||||||
REQUIRE(synth.getNumRegions() == 2);
|
REQUIRE(synth.getNumRegions() == 2);
|
||||||
REQUIRE(synth.getRegionView(0)->sampleId.filename() == "mono_sample.wav");
|
REQUIRE(synth.getRegionView(0)->sampleId->filename() == "mono_sample.wav");
|
||||||
REQUIRE(!synth.getRegionView(0)->isStereo());
|
REQUIRE(!synth.getRegionView(0)->isStereo());
|
||||||
REQUIRE(synth.getRegionView(1)->sampleId.filename() == "stereo_sample.wav");
|
REQUIRE(synth.getRegionView(1)->sampleId->filename() == "stereo_sample.wav");
|
||||||
REQUIRE(synth.getRegionView(1)->isStereo());
|
REQUIRE(synth.getRegionView(1)->isStereo());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -277,7 +277,7 @@ TEST_CASE("[Files] Channels (channels_multi.sfz)")
|
||||||
|
|
||||||
// generator only
|
// generator only
|
||||||
region = synth.getRegionView(regionNumber++);
|
region = synth.getRegionView(regionNumber++);
|
||||||
REQUIRE(region->sampleId.filename() == "*sine");
|
REQUIRE(region->sampleId->filename() == "*sine");
|
||||||
REQUIRE(!region->isStereo());
|
REQUIRE(!region->isStereo());
|
||||||
REQUIRE(region->isGenerator());
|
REQUIRE(region->isGenerator());
|
||||||
REQUIRE(region->isOscillator());
|
REQUIRE(region->isOscillator());
|
||||||
|
|
@ -285,7 +285,7 @@ TEST_CASE("[Files] Channels (channels_multi.sfz)")
|
||||||
|
|
||||||
// generator with multi
|
// generator with multi
|
||||||
region = synth.getRegionView(regionNumber++);
|
region = synth.getRegionView(regionNumber++);
|
||||||
REQUIRE(region->sampleId.filename() == "*sine");
|
REQUIRE(region->sampleId->filename() == "*sine");
|
||||||
REQUIRE(region->isStereo());
|
REQUIRE(region->isStereo());
|
||||||
REQUIRE(region->isGenerator());
|
REQUIRE(region->isGenerator());
|
||||||
REQUIRE(region->isOscillator());
|
REQUIRE(region->isOscillator());
|
||||||
|
|
@ -293,7 +293,7 @@ TEST_CASE("[Files] Channels (channels_multi.sfz)")
|
||||||
|
|
||||||
// explicit wavetable
|
// explicit wavetable
|
||||||
region = synth.getRegionView(regionNumber++);
|
region = synth.getRegionView(regionNumber++);
|
||||||
REQUIRE(region->sampleId.filename() == "ramp_wave.wav");
|
REQUIRE(region->sampleId->filename() == "ramp_wave.wav");
|
||||||
REQUIRE(!region->isStereo());
|
REQUIRE(!region->isStereo());
|
||||||
REQUIRE(!region->isGenerator());
|
REQUIRE(!region->isGenerator());
|
||||||
REQUIRE(region->isOscillator());
|
REQUIRE(region->isOscillator());
|
||||||
|
|
@ -301,7 +301,7 @@ TEST_CASE("[Files] Channels (channels_multi.sfz)")
|
||||||
|
|
||||||
// explicit wavetable with multi
|
// explicit wavetable with multi
|
||||||
region = synth.getRegionView(regionNumber++);
|
region = synth.getRegionView(regionNumber++);
|
||||||
REQUIRE(region->sampleId.filename() == "ramp_wave.wav");
|
REQUIRE(region->sampleId->filename() == "ramp_wave.wav");
|
||||||
REQUIRE(region->isStereo());
|
REQUIRE(region->isStereo());
|
||||||
REQUIRE(!region->isGenerator());
|
REQUIRE(!region->isGenerator());
|
||||||
REQUIRE(region->isOscillator());
|
REQUIRE(region->isOscillator());
|
||||||
|
|
@ -309,7 +309,7 @@ TEST_CASE("[Files] Channels (channels_multi.sfz)")
|
||||||
|
|
||||||
// explicit disabled wavetable
|
// explicit disabled wavetable
|
||||||
region = synth.getRegionView(regionNumber++);
|
region = synth.getRegionView(regionNumber++);
|
||||||
REQUIRE(region->sampleId.filename() == "ramp_wave.wav");
|
REQUIRE(region->sampleId->filename() == "ramp_wave.wav");
|
||||||
REQUIRE(!region->isStereo());
|
REQUIRE(!region->isStereo());
|
||||||
REQUIRE(!region->isGenerator());
|
REQUIRE(!region->isGenerator());
|
||||||
REQUIRE(!region->isOscillator());
|
REQUIRE(!region->isOscillator());
|
||||||
|
|
@ -317,7 +317,7 @@ TEST_CASE("[Files] Channels (channels_multi.sfz)")
|
||||||
|
|
||||||
// explicit disabled wavetable with multi
|
// explicit disabled wavetable with multi
|
||||||
region = synth.getRegionView(regionNumber++);
|
region = synth.getRegionView(regionNumber++);
|
||||||
REQUIRE(region->sampleId.filename() == "ramp_wave.wav");
|
REQUIRE(region->sampleId->filename() == "ramp_wave.wav");
|
||||||
REQUIRE(!region->isStereo());
|
REQUIRE(!region->isStereo());
|
||||||
REQUIRE(!region->isGenerator());
|
REQUIRE(!region->isGenerator());
|
||||||
REQUIRE(!region->isOscillator());
|
REQUIRE(!region->isOscillator());
|
||||||
|
|
@ -325,7 +325,7 @@ TEST_CASE("[Files] Channels (channels_multi.sfz)")
|
||||||
|
|
||||||
// implicit wavetable (sound file < 3000 frames)
|
// implicit wavetable (sound file < 3000 frames)
|
||||||
region = synth.getRegionView(regionNumber++);
|
region = synth.getRegionView(regionNumber++);
|
||||||
REQUIRE(region->sampleId.filename() == "ramp_wave.wav");
|
REQUIRE(region->sampleId->filename() == "ramp_wave.wav");
|
||||||
REQUIRE(!region->isStereo());
|
REQUIRE(!region->isStereo());
|
||||||
REQUIRE(!region->isGenerator());
|
REQUIRE(!region->isGenerator());
|
||||||
REQUIRE(region->isOscillator());
|
REQUIRE(region->isOscillator());
|
||||||
|
|
@ -333,7 +333,7 @@ TEST_CASE("[Files] Channels (channels_multi.sfz)")
|
||||||
|
|
||||||
// implicit non-wavetable (sound file >= 3000 frames)
|
// implicit non-wavetable (sound file >= 3000 frames)
|
||||||
region = synth.getRegionView(regionNumber++);
|
region = synth.getRegionView(regionNumber++);
|
||||||
REQUIRE(region->sampleId.filename() == "snare.wav");
|
REQUIRE(region->sampleId->filename() == "snare.wav");
|
||||||
REQUIRE(!region->isStereo());
|
REQUIRE(!region->isStereo());
|
||||||
REQUIRE(!region->isGenerator());
|
REQUIRE(!region->isGenerator());
|
||||||
REQUIRE(!region->isOscillator());
|
REQUIRE(!region->isOscillator());
|
||||||
|
|
@ -341,7 +341,7 @@ TEST_CASE("[Files] Channels (channels_multi.sfz)")
|
||||||
|
|
||||||
// generator with multi=1 (single)
|
// generator with multi=1 (single)
|
||||||
region = synth.getRegionView(regionNumber++);
|
region = synth.getRegionView(regionNumber++);
|
||||||
REQUIRE(region->sampleId.filename() == "*sine");
|
REQUIRE(region->sampleId->filename() == "*sine");
|
||||||
REQUIRE(!region->isStereo());
|
REQUIRE(!region->isStereo());
|
||||||
REQUIRE(region->isGenerator());
|
REQUIRE(region->isGenerator());
|
||||||
REQUIRE(region->isOscillator());
|
REQUIRE(region->isOscillator());
|
||||||
|
|
@ -349,7 +349,7 @@ TEST_CASE("[Files] Channels (channels_multi.sfz)")
|
||||||
|
|
||||||
// generator with multi=2 (ring modulation)
|
// generator with multi=2 (ring modulation)
|
||||||
region = synth.getRegionView(regionNumber++);
|
region = synth.getRegionView(regionNumber++);
|
||||||
REQUIRE(region->sampleId.filename() == "*sine");
|
REQUIRE(region->sampleId->filename() == "*sine");
|
||||||
REQUIRE(!region->isStereo());
|
REQUIRE(!region->isStereo());
|
||||||
REQUIRE(region->isGenerator());
|
REQUIRE(region->isGenerator());
|
||||||
REQUIRE(region->isOscillator());
|
REQUIRE(region->isOscillator());
|
||||||
|
|
@ -424,7 +424,7 @@ TEST_CASE("[Files] Specific bug: relative path with backslashes")
|
||||||
Synth synth;
|
Synth synth;
|
||||||
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/SpecificBugs/win_backslashes.sfz");
|
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/SpecificBugs/win_backslashes.sfz");
|
||||||
REQUIRE(synth.getNumRegions() == 1);
|
REQUIRE(synth.getNumRegions() == 1);
|
||||||
REQUIRE(synth.getRegionView(0)->sampleId.filename() == R"(Xylo/Subfolder/closedhat.wav)");
|
REQUIRE(synth.getRegionView(0)->sampleId->filename() == R"(Xylo/Subfolder/closedhat.wav)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Files] Default path")
|
TEST_CASE("[Files] Default path")
|
||||||
|
|
@ -432,10 +432,10 @@ TEST_CASE("[Files] Default path")
|
||||||
Synth synth;
|
Synth synth;
|
||||||
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/default_path.sfz");
|
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/default_path.sfz");
|
||||||
REQUIRE(synth.getNumRegions() == 4);
|
REQUIRE(synth.getNumRegions() == 4);
|
||||||
REQUIRE(synth.getRegionView(0)->sampleId.filename() == R"(DefaultPath/SubPath1/sample1.wav)");
|
REQUIRE(synth.getRegionView(0)->sampleId->filename() == R"(DefaultPath/SubPath1/sample1.wav)");
|
||||||
REQUIRE(synth.getRegionView(1)->sampleId.filename() == R"(DefaultPath/SubPath2/sample2.wav)");
|
REQUIRE(synth.getRegionView(1)->sampleId->filename() == R"(DefaultPath/SubPath2/sample2.wav)");
|
||||||
REQUIRE(synth.getRegionView(2)->sampleId.filename() == R"(DefaultPath/SubPath1/sample1.wav)");
|
REQUIRE(synth.getRegionView(2)->sampleId->filename() == R"(DefaultPath/SubPath1/sample1.wav)");
|
||||||
REQUIRE(synth.getRegionView(3)->sampleId.filename() == R"(DefaultPath/SubPath2/sample2.wav)");
|
REQUIRE(synth.getRegionView(3)->sampleId->filename() == R"(DefaultPath/SubPath2/sample2.wav)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Files] Default path reset when calling loadSfzFile again")
|
TEST_CASE("[Files] Default path reset when calling loadSfzFile again")
|
||||||
|
|
@ -445,7 +445,7 @@ TEST_CASE("[Files] Default path reset when calling loadSfzFile again")
|
||||||
REQUIRE(synth.getNumRegions() == 4);
|
REQUIRE(synth.getNumRegions() == 4);
|
||||||
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/default_path_reset.sfz");
|
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/default_path_reset.sfz");
|
||||||
REQUIRE(synth.getNumRegions() == 1);
|
REQUIRE(synth.getNumRegions() == 1);
|
||||||
REQUIRE(synth.getRegionView(0)->sampleId.filename() == R"(DefaultPath/SubPath2/sample2.wav)");
|
REQUIRE(synth.getRegionView(0)->sampleId->filename() == R"(DefaultPath/SubPath2/sample2.wav)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Files] Default path is ignored for generators")
|
TEST_CASE("[Files] Default path is ignored for generators")
|
||||||
|
|
@ -453,7 +453,7 @@ TEST_CASE("[Files] Default path is ignored for generators")
|
||||||
Synth synth;
|
Synth synth;
|
||||||
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/default_path_generator.sfz");
|
synth.loadSfzFile(fs::current_path() / "tests/TestFiles/default_path_generator.sfz");
|
||||||
REQUIRE(synth.getNumRegions() == 1);
|
REQUIRE(synth.getNumRegions() == 1);
|
||||||
REQUIRE(synth.getRegionView(0)->sampleId.filename() == R"(*sine)");
|
REQUIRE(synth.getRegionView(0)->sampleId->filename() == R"(*sine)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Files] Set CC applies properly")
|
TEST_CASE("[Files] Set CC applies properly")
|
||||||
|
|
@ -616,10 +616,10 @@ TEST_CASE("[Files] Case sentitiveness")
|
||||||
Synth synth;
|
Synth synth;
|
||||||
synth.loadSfzFile(sfzFilePath);
|
synth.loadSfzFile(sfzFilePath);
|
||||||
REQUIRE(synth.getNumRegions() == 4);
|
REQUIRE(synth.getNumRegions() == 4);
|
||||||
REQUIRE(synth.getRegionView(0)->sampleId.filename() == "dummy1.wav");
|
REQUIRE(synth.getRegionView(0)->sampleId->filename() == "dummy1.wav");
|
||||||
REQUIRE(synth.getRegionView(1)->sampleId.filename() == "Regions/dummy.wav");
|
REQUIRE(synth.getRegionView(1)->sampleId->filename() == "Regions/dummy.wav");
|
||||||
REQUIRE(synth.getRegionView(2)->sampleId.filename() == "Regions/dummy.wav");
|
REQUIRE(synth.getRegionView(2)->sampleId->filename() == "Regions/dummy.wav");
|
||||||
REQUIRE(synth.getRegionView(3)->sampleId.filename() == "Regions/dummy.wav");
|
REQUIRE(synth.getRegionView(3)->sampleId->filename() == "Regions/dummy.wav");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,18 +23,18 @@ TEST_CASE("[Region] Parsing opcodes")
|
||||||
|
|
||||||
SECTION("sample")
|
SECTION("sample")
|
||||||
{
|
{
|
||||||
REQUIRE(region.sampleId.filename() == "");
|
REQUIRE(region.sampleId->filename() == "");
|
||||||
region.parseOpcode({ "sample", "dummy.wav" });
|
region.parseOpcode({ "sample", "dummy.wav" });
|
||||||
REQUIRE(region.sampleId.filename() == "dummy.wav");
|
REQUIRE(region.sampleId->filename() == "dummy.wav");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("direction")
|
SECTION("direction")
|
||||||
{
|
{
|
||||||
REQUIRE(!region.sampleId.isReverse());
|
REQUIRE(!region.sampleId->isReverse());
|
||||||
region.parseOpcode({ "direction", "reverse" });
|
region.parseOpcode({ "direction", "reverse" });
|
||||||
REQUIRE(region.sampleId.isReverse());
|
REQUIRE(region.sampleId->isReverse());
|
||||||
region.parseOpcode({ "direction", "forward" });
|
region.parseOpcode({ "direction", "forward" });
|
||||||
REQUIRE(!region.sampleId.isReverse());
|
REQUIRE(!region.sampleId->isReverse());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("delay")
|
SECTION("delay")
|
||||||
|
|
|
||||||
|
|
@ -698,13 +698,13 @@ TEST_CASE("[Synth] Release (basic behavior with sample)")
|
||||||
)");
|
)");
|
||||||
synth.noteOn(0, 62, 85);
|
synth.noteOn(0, 62, 85);
|
||||||
REQUIRE( numPlayingVoices(synth) == 1 );
|
REQUIRE( numPlayingVoices(synth) == 1 );
|
||||||
REQUIRE( getPlayingVoices(synth).front()->getRegion()->sampleId.filename() == "*sine" );
|
REQUIRE( getPlayingVoices(synth).front()->getRegion()->sampleId->filename() == "*sine" );
|
||||||
synth.noteOff(0, 62, 85);
|
synth.noteOff(0, 62, 85);
|
||||||
REQUIRE( numPlayingVoices(synth) == 1 );
|
REQUIRE( numPlayingVoices(synth) == 1 );
|
||||||
REQUIRE( getPlayingVoices(synth).front()->getRegion()->sampleId.filename() == "closedhat.wav" );
|
REQUIRE( getPlayingVoices(synth).front()->getRegion()->sampleId->filename() == "closedhat.wav" );
|
||||||
synth.renderBlock(buffer);
|
synth.renderBlock(buffer);
|
||||||
REQUIRE( numPlayingVoices(synth) == 1 );
|
REQUIRE( numPlayingVoices(synth) == 1 );
|
||||||
REQUIRE( getPlayingVoices(synth).front()->getRegion()->sampleId.filename() == "closedhat.wav" );
|
REQUIRE( getPlayingVoices(synth).front()->getRegion()->sampleId->filename() == "closedhat.wav" );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Synth] Release key (basic behavior with sample)")
|
TEST_CASE("[Synth] Release key (basic behavior with sample)")
|
||||||
|
|
@ -720,7 +720,7 @@ TEST_CASE("[Synth] Release key (basic behavior with sample)")
|
||||||
REQUIRE( numPlayingVoices(synth) == 1 );
|
REQUIRE( numPlayingVoices(synth) == 1 );
|
||||||
synth.renderBlock(buffer);
|
synth.renderBlock(buffer);
|
||||||
REQUIRE( numPlayingVoices(synth) == 1 );
|
REQUIRE( numPlayingVoices(synth) == 1 );
|
||||||
REQUIRE( getPlayingVoices(synth).front()->getRegion()->sampleId.filename() == "closedhat.wav" );
|
REQUIRE( getPlayingVoices(synth).front()->getRegion()->sampleId->filename() == "closedhat.wav" );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Synth] Release key (pedal)")
|
TEST_CASE("[Synth] Release key (pedal)")
|
||||||
|
|
@ -1338,15 +1338,15 @@ TEST_CASE("[Synth] Off by with CC switches")
|
||||||
)");
|
)");
|
||||||
synth.noteOn(0, 60, 85);
|
synth.noteOn(0, 60, 85);
|
||||||
REQUIRE( numPlayingVoices(synth) == 1 );
|
REQUIRE( numPlayingVoices(synth) == 1 );
|
||||||
REQUIRE( getPlayingVoices(synth).front()->getRegion()->sampleId.filename() == "*saw" );
|
REQUIRE( getPlayingVoices(synth).front()->getRegion()->sampleId->filename() == "*saw" );
|
||||||
synth.cc(0, 4, 127);
|
synth.cc(0, 4, 127);
|
||||||
synth.noteOn(0, 60, 85);
|
synth.noteOn(0, 60, 85);
|
||||||
REQUIRE( numPlayingVoices(synth) == 1 );
|
REQUIRE( numPlayingVoices(synth) == 1 );
|
||||||
REQUIRE( getPlayingVoices(synth).front()->getRegion()->sampleId.filename() == "*triangle" );
|
REQUIRE( getPlayingVoices(synth).front()->getRegion()->sampleId->filename() == "*triangle" );
|
||||||
synth.cc(0, 4, 0);
|
synth.cc(0, 4, 0);
|
||||||
synth.noteOn(0, 60, 85);
|
synth.noteOn(0, 60, 85);
|
||||||
REQUIRE( numPlayingVoices(synth) == 1 );
|
REQUIRE( numPlayingVoices(synth) == 1 );
|
||||||
REQUIRE( getPlayingVoices(synth).front()->getRegion()->sampleId.filename() == "*saw" );
|
REQUIRE( getPlayingVoices(synth).front()->getRegion()->sampleId->filename() == "*saw" );
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Synth] Initial values of CC")
|
TEST_CASE("[Synth] Initial values of CC")
|
||||||
|
|
|
||||||
|
|
@ -118,9 +118,12 @@ endif()
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
if (NOT MSVC)
|
if (NOT MSVC)
|
||||||
install (DIRECTORY "${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}"
|
install(DIRECTORY "${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}"
|
||||||
DESTINATION "${VSTPLUGIN_INSTALL_DIR}"
|
DESTINATION "${VSTPLUGIN_INSTALL_DIR}"
|
||||||
COMPONENT "vst")
|
COMPONENT "vst")
|
||||||
|
bundle_dylibs(vst
|
||||||
|
"${VSTPLUGIN_INSTALL_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/MacOS/sfizz"
|
||||||
|
COMPONENT "vst")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# --- Audio Unit wrapper --- #
|
# --- Audio Unit wrapper --- #
|
||||||
|
|
@ -252,7 +255,7 @@ elseif(SFIZZ_AU)
|
||||||
DESTINATION "${PROJECT_BINARY_DIR}/${AUPLUGIN_BUNDLE_NAME}")
|
DESTINATION "${PROJECT_BINARY_DIR}/${AUPLUGIN_BUNDLE_NAME}")
|
||||||
|
|
||||||
# Add the resource fork
|
# Add the resource fork
|
||||||
if (FALSE) # optional, disabled because broken on CI
|
if (TRUE)
|
||||||
execute_process(COMMAND "xcrun" "--find" "Rez"
|
execute_process(COMMAND "xcrun" "--find" "Rez"
|
||||||
OUTPUT_VARIABLE OSX_REZ_COMMAND OUTPUT_STRIP_TRAILING_WHITESPACE)
|
OUTPUT_VARIABLE OSX_REZ_COMMAND OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include")
|
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include")
|
||||||
|
|
@ -275,13 +278,6 @@ elseif(SFIZZ_AU)
|
||||||
"${VST3SDK_BASEDIR}/public.sdk/source/vst/auwrapper/auresource.r")
|
"${VST3SDK_BASEDIR}/public.sdk/source/vst/auwrapper/auresource.r")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Copy VST3 in the bundle
|
|
||||||
add_custom_command(TARGET ${VSTPLUGIN_PRJ_NAME} POST_BUILD COMMAND
|
|
||||||
"${CMAKE_COMMAND}" "-E"
|
|
||||||
"copy_directory"
|
|
||||||
"${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}"
|
|
||||||
"${PROJECT_BINARY_DIR}/${AUPLUGIN_BUNDLE_NAME}/Contents/Resources/plugin.vst3")
|
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||||
target_compile_options(${AUPLUGIN_PRJ_NAME} PRIVATE
|
target_compile_options(${AUPLUGIN_PRJ_NAME} PRIVATE
|
||||||
"-Wno-extra"
|
"-Wno-extra"
|
||||||
|
|
@ -300,5 +296,14 @@ elseif(SFIZZ_AU)
|
||||||
install(DIRECTORY "${PROJECT_BINARY_DIR}/${AUPLUGIN_BUNDLE_NAME}"
|
install(DIRECTORY "${PROJECT_BINARY_DIR}/${AUPLUGIN_BUNDLE_NAME}"
|
||||||
DESTINATION "${AUPLUGIN_INSTALL_DIR}"
|
DESTINATION "${AUPLUGIN_INSTALL_DIR}"
|
||||||
COMPONENT "au")
|
COMPONENT "au")
|
||||||
|
install(DIRECTORY "${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/"
|
||||||
|
DESTINATION "${AUPLUGIN_INSTALL_DIR}/${AUPLUGIN_BUNDLE_NAME}/Contents/Resources/plugin.vst3"
|
||||||
|
COMPONENT "au")
|
||||||
|
bundle_dylibs(au
|
||||||
|
"${AUPLUGIN_INSTALL_DIR}/${AUPLUGIN_BUNDLE_NAME}/Contents/MacOS/sfizz"
|
||||||
|
COMPONENT "au")
|
||||||
|
bundle_dylibs(au-vst
|
||||||
|
"${AUPLUGIN_INSTALL_DIR}/${AUPLUGIN_BUNDLE_NAME}/Contents/Resources/plugin.vst3/Contents/MacOS/sfizz"
|
||||||
|
COMPONENT "au")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
2
vst/external/VST_SDK/VST3_SDK/public.sdk
vendored
2
vst/external/VST_SDK/VST3_SDK/public.sdk
vendored
|
|
@ -1 +1 @@
|
||||||
Subproject commit ff836e8c02bd28c902f5e3e75353a86f65008a77
|
Subproject commit b63097ebce2105845aa97d04808fca4dfd51307c
|
||||||
Loading…
Add table
Reference in a new issue