Merge branch 'develop' into master
3
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
.* export-ignore
|
||||||
|
.*/** export-ignore
|
||||||
|
appveyor.yml export-ignore
|
||||||
2
.gitignore
vendored
|
|
@ -21,6 +21,8 @@ clients/sfzprint
|
||||||
|
|
||||||
/vst/download/
|
/vst/download/
|
||||||
|
|
||||||
|
/editor/external/fluentui-system-icons/
|
||||||
|
|
||||||
# gh-pages unstaged files:
|
# gh-pages unstaged files:
|
||||||
_api/
|
_api/
|
||||||
_site/
|
_site/
|
||||||
|
|
|
||||||
4
.gitmodules
vendored
|
|
@ -1,6 +1,6 @@
|
||||||
[submodule "external/abseil-cpp"]
|
[submodule "external/abseil-cpp"]
|
||||||
path = external/abseil-cpp
|
path = external/abseil-cpp
|
||||||
url = https://github.com/abseil/abseil-cpp
|
url = https://github.com/abseil/abseil-cpp.git
|
||||||
branch = lts_2020_02_25
|
branch = lts_2020_02_25
|
||||||
shallow = true
|
shallow = true
|
||||||
[submodule "vst/external/VST_SDK/VST3_SDK/base"]
|
[submodule "vst/external/VST_SDK/VST3_SDK/base"]
|
||||||
|
|
@ -16,6 +16,6 @@
|
||||||
url = https://github.com/sfztools/vst3_public_sdk.git
|
url = https://github.com/sfztools/vst3_public_sdk.git
|
||||||
shallow = true
|
shallow = true
|
||||||
[submodule "vst/external/VST_SDK/VST3_SDK/vstgui4"]
|
[submodule "vst/external/VST_SDK/VST3_SDK/vstgui4"]
|
||||||
path = vst/external/VST_SDK/VST3_SDK/vstgui4
|
path = editor/external/vstgui4
|
||||||
url = https://github.com/sfztools/vstgui.git
|
url = https://github.com/sfztools/vstgui.git
|
||||||
shallow = true
|
shallow = true
|
||||||
|
|
|
||||||
61
.travis.yml
|
|
@ -40,8 +40,33 @@ jobs:
|
||||||
install: .travis/download_cmake.sh
|
install: .travis/download_cmake.sh
|
||||||
script: .travis/script_test.sh
|
script: .travis/script_test.sh
|
||||||
|
|
||||||
- name: "Windows mingw32"
|
- name: "macOS"
|
||||||
stage: "Build"
|
stage: "Build"
|
||||||
|
os: osx
|
||||||
|
osx_image: xcode11.3
|
||||||
|
addons:
|
||||||
|
homebrew:
|
||||||
|
packages:
|
||||||
|
- cmake
|
||||||
|
- libsndfile
|
||||||
|
- jack
|
||||||
|
- dylibbundler
|
||||||
|
env:
|
||||||
|
- INSTALL_DIR="sfizz-${TRAVIS_BRANCH}-${TRAVIS_OS_NAME}-${TRAVIS_CPU_ARCH}"
|
||||||
|
script: .travis/script_osx.sh
|
||||||
|
after_success: .travis/prepare_osx.sh
|
||||||
|
|
||||||
|
- name: "MOD devices arm"
|
||||||
|
env:
|
||||||
|
- CONTAINER=jpcima/mod-plugin-builder
|
||||||
|
- CROSS_COMPILE=moddevices-arm
|
||||||
|
- INSTALL_DIR="sfizz-${TRAVIS_BRANCH}-moddevices"
|
||||||
|
before_install: .travis/before_install_moddevices.sh
|
||||||
|
install: .travis/install_moddevices.sh
|
||||||
|
script: .travis/script_moddevices.sh
|
||||||
|
after_success: .travis/prepare_tarball.sh
|
||||||
|
|
||||||
|
- name: "Windows mingw32"
|
||||||
env:
|
env:
|
||||||
- CROSS_COMPILE=mingw32
|
- CROSS_COMPILE=mingw32
|
||||||
- CONTAINER=archlinux
|
- CONTAINER=archlinux
|
||||||
|
|
@ -92,6 +117,7 @@ jobs:
|
||||||
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
|
||||||
|
- ENABLE_LV2_UI=OFF
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
|
|
@ -107,6 +133,7 @@ jobs:
|
||||||
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=ON
|
- ENABLE_VST_PLUGIN=ON
|
||||||
|
- ENABLE_LV2_UI=ON
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
|
|
@ -127,28 +154,9 @@ jobs:
|
||||||
script: .travis/script_plugins.sh
|
script: .travis/script_plugins.sh
|
||||||
after_success: .travis/prepare_tarball.sh
|
after_success: .travis/prepare_tarball.sh
|
||||||
|
|
||||||
- name: "macOS"
|
|
||||||
os: osx
|
|
||||||
env:
|
|
||||||
- INSTALL_DIR="sfizz-${TRAVIS_BRANCH}-${TRAVIS_OS_NAME}-${TRAVIS_CPU_ARCH}"
|
|
||||||
install: .travis/install_osx.sh
|
|
||||||
script: .travis/script_osx.sh
|
|
||||||
after_success: .travis/prepare_osx.sh
|
|
||||||
|
|
||||||
- name: "MOD devices arm"
|
|
||||||
stage: "Build"
|
|
||||||
env:
|
|
||||||
- CONTAINER=jpcima/mod-plugin-builder
|
|
||||||
- CROSS_COMPILE=moddevices-arm
|
|
||||||
- INSTALL_DIR="sfizz-${TRAVIS_BRANCH}-moddevices"
|
|
||||||
before_install: .travis/before_install_moddevices.sh
|
|
||||||
install: .travis/install_moddevices.sh
|
|
||||||
script: .travis/script_moddevices.sh
|
|
||||||
after_success: .travis/prepare_tarball.sh
|
|
||||||
|
|
||||||
- stage: "Deploy"
|
- stage: "Deploy"
|
||||||
name: "Source packaging"
|
name: "Source packaging"
|
||||||
if: (tag IS present) AND (branch = master) AND (type = push)
|
if: (tag =~ /^v?[0-9]/) AND (type = push)
|
||||||
env:
|
env:
|
||||||
- INSTALL_DIR="sfizz-${TRAVIS_BRANCH}-src"
|
- INSTALL_DIR="sfizz-${TRAVIS_BRANCH}-src"
|
||||||
addons:
|
addons:
|
||||||
|
|
@ -158,17 +166,6 @@ jobs:
|
||||||
install: sudo pip install git-archive-all
|
install: sudo pip install git-archive-all
|
||||||
script: git-archive-all --prefix="sfizz-${TRAVIS_BRANCH}/" -9 "${INSTALL_DIR}.tar.gz"
|
script: git-archive-all --prefix="sfizz-${TRAVIS_BRANCH}/" -9 "${INSTALL_DIR}.tar.gz"
|
||||||
|
|
||||||
- name: "Generate documentation"
|
|
||||||
if: (tag IS present) AND (branch = master) AND (type = push)
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- doxygen
|
|
||||||
- cmake
|
|
||||||
- libsndfile-dev
|
|
||||||
install: skip
|
|
||||||
script: .travis/update_dox.sh
|
|
||||||
|
|
||||||
- name: "Discord Webhook"
|
- name: "Discord Webhook"
|
||||||
install: skip
|
install: skip
|
||||||
script: bash ${TRAVIS_BUILD_DIR}/.travis/discord_webhook.sh success
|
script: bash ${TRAVIS_BUILD_DIR}/.travis/discord_webhook.sh success
|
||||||
|
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -ex
|
|
||||||
|
|
||||||
sudo ln -s /usr/local /opt/local
|
|
||||||
brew update
|
|
||||||
brew upgrade cmake
|
|
||||||
brew install python || brew link --overwrite python
|
|
||||||
brew install jack
|
|
||||||
brew install dylibbundler
|
|
||||||
|
|
@ -15,7 +15,8 @@ buildenv make DESTDIR=${PWD}/${INSTALL_DIR} install
|
||||||
|
|
||||||
# Bundle LV2 dependencies
|
# Bundle LV2 dependencies
|
||||||
cd "${INSTALL_DIR}"/Library/Audio/Plug-Ins/LV2
|
cd "${INSTALL_DIR}"/Library/Audio/Plug-Ins/LV2
|
||||||
dylibbundler -od -b -x sfizz.lv2/sfizz.so -d sfizz.lv2/libs/ -p @loader_path/libs/
|
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"
|
cd "${TRAVIS_BUILD_DIR}/build"
|
||||||
|
|
||||||
# Bundle VST3 dependencies
|
# Bundle VST3 dependencies
|
||||||
|
|
|
||||||
|
|
@ -8,4 +8,4 @@ cmake -DCMAKE_BUILD_TYPE=Release \
|
||||||
-DSFIZZ_TESTS=OFF \
|
-DSFIZZ_TESTS=OFF \
|
||||||
-DCMAKE_CXX_STANDARD=17 \
|
-DCMAKE_CXX_STANDARD=17 \
|
||||||
..
|
..
|
||||||
make -j$(nproc)
|
make -j2
|
||||||
|
|
|
||||||
|
|
@ -9,17 +9,17 @@ if [[ ${CROSS_COMPILE} == "mingw32" ]]; then
|
||||||
-DENABLE_LTO=OFF \
|
-DENABLE_LTO=OFF \
|
||||||
-DSFIZZ_JACK=OFF \
|
-DSFIZZ_JACK=OFF \
|
||||||
-DSFIZZ_VST=ON \
|
-DSFIZZ_VST=ON \
|
||||||
-DSFIZZ_STATIC_LIBSNDFILE=ON \
|
-DSFIZZ_STATIC_DEPENDENCIES=ON \
|
||||||
-DCMAKE_CXX_STANDARD=17 \
|
-DCMAKE_CXX_STANDARD=17 \
|
||||||
..
|
..
|
||||||
buildenv make -j$(nproc)
|
buildenv make -j2
|
||||||
elif [[ ${CROSS_COMPILE} == "mingw64" ]]; then
|
elif [[ ${CROSS_COMPILE} == "mingw64" ]]; then
|
||||||
buildenv x86_64-w64-mingw32-cmake -DCMAKE_BUILD_TYPE=Release \
|
buildenv x86_64-w64-mingw32-cmake -DCMAKE_BUILD_TYPE=Release \
|
||||||
-DENABLE_LTO=OFF \
|
-DENABLE_LTO=OFF \
|
||||||
-DSFIZZ_JACK=OFF \
|
-DSFIZZ_JACK=OFF \
|
||||||
-DSFIZZ_VST=ON \
|
-DSFIZZ_VST=ON \
|
||||||
-DSFIZZ_STATIC_LIBSNDFILE=ON \
|
-DSFIZZ_STATIC_DEPENDENCIES=ON \
|
||||||
-DCMAKE_CXX_STANDARD=17 \
|
-DCMAKE_CXX_STANDARD=17 \
|
||||||
..
|
..
|
||||||
buildenv make -j$(nproc)
|
buildenv make -j2
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -7,5 +7,5 @@ mkdir -p build/${INSTALL_DIR} && cd build
|
||||||
|
|
||||||
buildenv mod-plugin-builder /usr/local/bin/cmake \
|
buildenv mod-plugin-builder /usr/local/bin/cmake \
|
||||||
-DSFIZZ_SYSTEM_PROCESSOR=armv7-a \
|
-DSFIZZ_SYSTEM_PROCESSOR=armv7-a \
|
||||||
-DCMAKE_BUILD_TYPE=Release -DSFIZZ_JACK=OFF ..
|
-DCMAKE_BUILD_TYPE=Release -DSFIZZ_JACK=OFF -DSFIZZ_LV2_UI=OFF ..
|
||||||
buildenv mod-plugin-builder make -j
|
buildenv mod-plugin-builder make -j2
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,10 @@ mkdir -p build/${INSTALL_DIR} && cd build
|
||||||
cmake -DCMAKE_BUILD_TYPE=Release \
|
cmake -DCMAKE_BUILD_TYPE=Release \
|
||||||
-DSFIZZ_JACK=OFF \
|
-DSFIZZ_JACK=OFF \
|
||||||
-DSFIZZ_VST="$ENABLE_VST_PLUGIN" \
|
-DSFIZZ_VST="$ENABLE_VST_PLUGIN" \
|
||||||
|
-DSFIZZ_LV2_UI="$ENABLE_LV2_UI" \
|
||||||
-DSFIZZ_TESTS=OFF \
|
-DSFIZZ_TESTS=OFF \
|
||||||
-DSFIZZ_SHARED=OFF \
|
-DSFIZZ_SHARED=OFF \
|
||||||
-DSFIZZ_STATIC_LIBSNDFILE=ON \
|
-DSFIZZ_STATIC_DEPENDENCIES=ON \
|
||||||
-DCMAKE_CXX_STANDARD=17 \
|
-DCMAKE_CXX_STANDARD=17 \
|
||||||
..
|
..
|
||||||
make -j$(nproc)
|
make -j2
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,9 @@ cmake -DCMAKE_BUILD_TYPE=Release \
|
||||||
-DSFIZZ_JACK=OFF \
|
-DSFIZZ_JACK=OFF \
|
||||||
-DSFIZZ_TESTS=ON \
|
-DSFIZZ_TESTS=ON \
|
||||||
-DSFIZZ_SHARED=OFF \
|
-DSFIZZ_SHARED=OFF \
|
||||||
-DSFIZZ_STATIC_LIBSNDFILE=OFF \
|
-DSFIZZ_STATIC_DEPENDENCIES=OFF \
|
||||||
-DSFIZZ_LV2=OFF \
|
-DSFIZZ_LV2=OFF \
|
||||||
-DCMAKE_CXX_STANDARD=17 \
|
-DCMAKE_CXX_STANDARD=17 \
|
||||||
..
|
..
|
||||||
make -j$(nproc) sfizz_tests
|
make -j2 sfizz_tests
|
||||||
tests/sfizz_tests
|
tests/sfizz_tests
|
||||||
|
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -x # No fail, we need to go back to the original branch at the end
|
|
||||||
. .travis/environment.sh
|
|
||||||
|
|
||||||
mkdir build && cd build && cmake -DSFIZZ_JACK=OFF -DSFIZZ_SHARED=OFF -DSFIZZ_LV2=OFF .. && cd ..
|
|
||||||
doxygen Doxyfile
|
|
||||||
./doxygen/scripts/generate_api_index.sh
|
|
||||||
git fetch --depth=1 https://github.com/${TRAVIS_REPO_SLUG}.git refs/heads/gh-pages:refs/remotes/origin/gh-pages
|
|
||||||
git checkout origin/gh-pages
|
|
||||||
git checkout -b gh-pages
|
|
||||||
mv _api api/${TRAVIS_TAG}
|
|
||||||
mv api_index.md api/index.md
|
|
||||||
git add api && git commit -m "Release ${TRAVIS_TAG} (Travis build: ${TRAVIS_BUILD_NUMBER})"
|
|
||||||
git remote add origin-pages https://${GITHUB_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git > /dev/null 2>&1
|
|
||||||
git push --quiet --set-upstream origin-pages gh-pages
|
|
||||||
git checkout ${TRAVIS_BRANCH}
|
|
||||||
|
|
@ -8,3 +8,5 @@ Contributors to `sfizz`, in chronologic order:
|
||||||
- Michael Willis (2020)
|
- Michael Willis (2020)
|
||||||
- Jean-Pierre Cimalando (2020)
|
- Jean-Pierre Cimalando (2020)
|
||||||
- Tobiasz "unfa" Karoń (2020)
|
- Tobiasz "unfa" Karoń (2020)
|
||||||
|
- Kinwie (2020)
|
||||||
|
- Atsushi Eno (2020)
|
||||||
|
|
|
||||||
|
|
@ -8,27 +8,21 @@ else()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
project (sfizz VERSION 0.4.0 LANGUAGES CXX C)
|
project (sfizz VERSION 0.5.0 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
|
||||||
set (CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
set (CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||||
include (BuildType)
|
include (BuildType)
|
||||||
include (SfizzConfig)
|
|
||||||
|
|
||||||
# Build Options
|
# Build Options
|
||||||
set (BUILD_TESTING OFF CACHE BOOL "Disable Abseil's tests [default: OFF]")
|
set (BUILD_TESTING OFF CACHE BOOL "Disable Abseil's tests [default: OFF]")
|
||||||
|
|
||||||
# On macOS add the needed directories for both library and jack client
|
|
||||||
if (APPLE)
|
|
||||||
include_directories (SYSTEM /usr/local/opt/libsndfile/include)
|
|
||||||
link_directories (/usr/local/opt/libsndfile/lib)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option (ENABLE_LTO "Enable Link Time Optimization [default: ON]" ON)
|
option (ENABLE_LTO "Enable Link Time Optimization [default: ON]" ON)
|
||||||
option (SFIZZ_JACK "Enable JACK stand-alone build [default: ON]" ON)
|
option (SFIZZ_JACK "Enable JACK stand-alone build [default: ON]" ON)
|
||||||
option (SFIZZ_RENDER "Enable renderer of SMF files [default: ON]" ON)
|
option (SFIZZ_RENDER "Enable renderer of SMF files [default: ON]" ON)
|
||||||
option (SFIZZ_LV2 "Enable LV2 plug-in build [default: ON]" ON)
|
option (SFIZZ_LV2 "Enable LV2 plug-in build [default: ON]" ON)
|
||||||
|
option (SFIZZ_LV2_UI "Enable LV2 plug-in user interface [default: ON]" ON)
|
||||||
option (SFIZZ_VST "Enable VST plug-in build [default: OFF]" OFF)
|
option (SFIZZ_VST "Enable VST plug-in build [default: OFF]" OFF)
|
||||||
option (SFIZZ_AU "Enable AU plug-in build [default: OFF]" OFF)
|
option (SFIZZ_AU "Enable AU plug-in build [default: OFF]" OFF)
|
||||||
option (SFIZZ_BENCHMARKS "Enable benchmarks build [default: OFF]" OFF)
|
option (SFIZZ_BENCHMARKS "Enable benchmarks build [default: OFF]" OFF)
|
||||||
|
|
@ -36,9 +30,11 @@ option (SFIZZ_TESTS "Enable tests build [default: OFF]" OFF)
|
||||||
option (SFIZZ_DEVTOOLS "Enable developer tools build [default: OFF]" OFF)
|
option (SFIZZ_DEVTOOLS "Enable developer tools build [default: OFF]" OFF)
|
||||||
option (SFIZZ_SHARED "Enable shared library build [default: ON]" ON)
|
option (SFIZZ_SHARED "Enable shared library build [default: ON]" ON)
|
||||||
option (SFIZZ_USE_VCPKG "Assume that sfizz is build using vcpkg [default: OFF]" OFF)
|
option (SFIZZ_USE_VCPKG "Assume that sfizz is build using vcpkg [default: OFF]" OFF)
|
||||||
option (SFIZZ_STATIC_LIBSNDFILE "Link libsndfile statically [default: OFF]" OFF)
|
option (SFIZZ_STATIC_DEPENDENCIES "Link dependencies statically [default: OFF]" OFF)
|
||||||
option (SFIZZ_RELEASE_ASSERTS "Forced assertions in release builds [default: OFF]" OFF)
|
option (SFIZZ_RELEASE_ASSERTS "Forced assertions in release builds [default: OFF]" OFF)
|
||||||
|
|
||||||
|
include (SfizzConfig)
|
||||||
|
|
||||||
# Don't use IPO in non Release builds
|
# Don't use IPO in non Release builds
|
||||||
include (CheckIPO)
|
include (CheckIPO)
|
||||||
|
|
||||||
|
|
@ -51,6 +47,10 @@ add_subdirectory (src)
|
||||||
# Optional targets
|
# Optional targets
|
||||||
add_subdirectory (clients)
|
add_subdirectory (clients)
|
||||||
|
|
||||||
|
if ((SFIZZ_LV2 AND SFIZZ_LV2_UI) OR SFIZZ_VST)
|
||||||
|
add_subdirectory (editor)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (SFIZZ_LV2)
|
if (SFIZZ_LV2)
|
||||||
add_subdirectory (lv2)
|
add_subdirectory (lv2)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -47,4 +47,10 @@ It is the role of maintainers to best adapt the governance model to the evolutio
|
||||||
3. Maintainers can be invited from regular contributors at any point in time; maintainers wishing to leave the governance of the project may inform the other maintainers.
|
3. Maintainers can be invited from regular contributors at any point in time; maintainers wishing to leave the governance of the project may inform the other maintainers.
|
||||||
In both cases, updates to this document reflect the evolution of the governance team and rules.
|
In both cases, updates to this document reflect the evolution of the governance team and rules.
|
||||||
|
|
||||||
|
## License for the GOVERNANCE.md file
|
||||||
|
|
||||||
|
Copying and distribution of this file, with or without modification,
|
||||||
|
are permitted in any medium without royalty provided that this notice
|
||||||
|
is preserved. This file is offered as-is, without any warranty.
|
||||||
|
|
||||||
[Open-source Open Collective]: https://opencollective.com/sfztools
|
[Open-source Open Collective]: https://opencollective.com/sfztools
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,7 @@ BSD 2-Clause License
|
||||||
The code is copyrighted by their respective authors, as indicated by the
|
The code is copyrighted by their respective authors, as indicated by the
|
||||||
source control mechanism.
|
source control mechanism.
|
||||||
|
|
||||||
Contributors include:
|
Please refer to AUTHORS.md for the list of contributors.
|
||||||
- Paul Ferrand (2019-) paul at ferrand dot cc
|
|
||||||
- Andrea Zanellato (2019-)
|
|
||||||
- Jean-Pierre Cimalando (2020-)
|
|
||||||
- Michael Willis (2020-)
|
|
||||||
- Alexander Mitchell (2020-)
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,10 @@
|
||||||
[![Travis Build Status]](https://travis-ci.com/sfztools/sfizz)
|
[![Travis Build Status]](https://travis-ci.com/sfztools/sfizz)
|
||||||
[![AppVeyor Build Status]](https://ci.appveyor.com/project/sfztools/sfizz)
|
[![AppVeyor Build Status]](https://ci.appveyor.com/project/sfztools/sfizz)
|
||||||
|
|
||||||
SFZ library and LV2 plugin, please check [our website] for more details.
|
[![Discord Badge Image]](https://discord.gg/3ArE9Mw)
|
||||||
|
|
||||||
|
SFZ parser and synth c++ library, providing AU / LV2 / VST3 plugins
|
||||||
|
and JACK standalone client, please check [our website] for more details.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
@ -64,3 +67,4 @@ The sfizz library also uses in some subprojects:
|
||||||
[build from source]: https://sfz.tools/sfizz/development/build/
|
[build from source]: https://sfz.tools/sfizz/development/build/
|
||||||
[AppVeyor Build Status]: https://img.shields.io/appveyor/ci/sfztools/sfizz.svg?label=Windows&style=popout&logo=appveyor
|
[AppVeyor Build Status]: https://img.shields.io/appveyor/ci/sfztools/sfizz.svg?label=Windows&style=popout&logo=appveyor
|
||||||
[Travis Build Status]: https://img.shields.io/travis/com/sfztools/sfizz.svg?label=Linux&style=popout&logo=travis
|
[Travis Build Status]: https://img.shields.io/travis/com/sfztools/sfizz.svg?label=Linux&style=popout&logo=travis
|
||||||
|
[Discord Badge Image]: https://img.shields.io/discord/587748534321807416?label=discord&logo=discord
|
||||||
|
|
|
||||||
10
appveyor.yml
|
|
@ -1,5 +1,5 @@
|
||||||
version: build-{build}
|
version: build-{build}
|
||||||
image: Visual Studio 2017
|
image: Visual Studio 2019
|
||||||
configuration: Release
|
configuration: Release
|
||||||
platform:
|
platform:
|
||||||
- Win32
|
- Win32
|
||||||
|
|
@ -12,20 +12,22 @@ install:
|
||||||
- cmd: set PATH=C:\Program Files (x86)\Inno Setup 6;%PATH%
|
- cmd: set PATH=C:\Program Files (x86)\Inno Setup 6;%PATH%
|
||||||
- cmd: if %platform%==Win32 set VCPKG_TRIPLET=x86-windows-static
|
- cmd: if %platform%==Win32 set VCPKG_TRIPLET=x86-windows-static
|
||||||
- cmd: if %platform%==x64 set VCPKG_TRIPLET=x64-windows-static
|
- cmd: if %platform%==x64 set VCPKG_TRIPLET=x64-windows-static
|
||||||
|
# - cmd: cd c:\tools\vcpkg\
|
||||||
|
# - cmd: git pull
|
||||||
|
# - cmd: .\bootstrap-vcpkg.bat
|
||||||
|
# - cmd: cd %APPVEYOR_BUILD_FOLDER%
|
||||||
- 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
|
||||||
- cmd: mkdir CMakeBuild
|
- cmd: mkdir CMakeBuild
|
||||||
- cmd: cd CMakeBuild
|
- cmd: cd CMakeBuild
|
||||||
- cmd: cmake .. -G"Visual Studio 15 2017" -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
|
||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
- cmd: cmake --build . --config Release -j
|
- cmd: cmake --build . --config Release -j
|
||||||
|
|
||||||
after_build:
|
after_build:
|
||||||
- cmd: cp sfizz.lv2/Release/sfizz.dll sfizz.lv2/
|
|
||||||
- cmd: rm -rf sfizz.lv2/Release
|
|
||||||
- cmd: if %platform%==Win32 set RELEASE_ARCH=x86
|
- cmd: if %platform%==Win32 set RELEASE_ARCH=x86
|
||||||
- cmd: if %platform%==x64 set RELEASE_ARCH=x64
|
- cmd: if %platform%==x64 set RELEASE_ARCH=x64
|
||||||
- cmd: 7z a sfizz-lv2-%APPVEYOR_REPO_TAG_NAME%-%RELEASE_ARCH%-msvc.zip sfizz.lv2
|
- cmd: 7z a sfizz-lv2-%APPVEYOR_REPO_TAG_NAME%-%RELEASE_ARCH%-msvc.zip sfizz.lv2
|
||||||
|
|
|
||||||
70
benchmarks/BM_allWithin.cpp
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#include "SIMDHelpers.h"
|
||||||
|
#include "Macros.h"
|
||||||
|
#include <benchmark/benchmark.h>
|
||||||
|
#include <random>
|
||||||
|
#include <numeric>
|
||||||
|
#include <vector>
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class WithinArray : public benchmark::Fixture {
|
||||||
|
public:
|
||||||
|
void SetUp(const ::benchmark::State& state) {
|
||||||
|
std::random_device rd { };
|
||||||
|
std::mt19937 gen { rd() };
|
||||||
|
std::uniform_real_distribution<float> dist { 1, 10 };
|
||||||
|
input = std::vector<float>(state.range(0));
|
||||||
|
std::generate(input.begin(), input.end(), [&]() { return dist(gen); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void TearDown(const ::benchmark::State& state) {
|
||||||
|
UNUSED(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<float> input;
|
||||||
|
};
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(WithinArray, ScalarFalse)(benchmark::State& state) {
|
||||||
|
for (auto _ : state)
|
||||||
|
{
|
||||||
|
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::allWithin, false);
|
||||||
|
sfz::allWithin<float>(input, 1.2f, 3.8f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(WithinArray, SIMDFalse)(benchmark::State& state) {
|
||||||
|
for (auto _ : state)
|
||||||
|
{
|
||||||
|
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::allWithin, true);
|
||||||
|
sfz::allWithin<float>(input, 1.2f, 3.8f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(WithinArray, ScalarTrue)(benchmark::State& state) {
|
||||||
|
for (auto _ : state)
|
||||||
|
{
|
||||||
|
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::allWithin, false);
|
||||||
|
sfz::allWithin<float>(input, 0.0f, 11.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(WithinArray, SIMDTrue)(benchmark::State& state) {
|
||||||
|
for (auto _ : state)
|
||||||
|
{
|
||||||
|
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::allWithin, true);
|
||||||
|
sfz::allWithin<float>(input, 0.0f, 11.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BENCHMARK_REGISTER_F(WithinArray, ScalarFalse)->RangeMultiplier(4)->Range(1 << 2, 1 << 12);
|
||||||
|
BENCHMARK_REGISTER_F(WithinArray, SIMDFalse)->RangeMultiplier(4)->Range(1 << 2, 1 << 12);
|
||||||
|
BENCHMARK_REGISTER_F(WithinArray, ScalarTrue)->RangeMultiplier(4)->Range(1 << 2, 1 << 12);
|
||||||
|
BENCHMARK_REGISTER_F(WithinArray, SIMDTrue)->RangeMultiplier(4)->Range(1 << 2, 1 << 12);
|
||||||
|
BENCHMARK_MAIN();
|
||||||
233
benchmarks/BM_audioReaders.cpp
Normal file
|
|
@ -0,0 +1,233 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#include "AudioReader.h"
|
||||||
|
#include <benchmark/benchmark.h>
|
||||||
|
#include <sndfile.hh>
|
||||||
|
#include <ghc/fs_std.hpp>
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
#include <system_error>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cmath>
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#else
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///
|
||||||
|
struct TemporaryFile {
|
||||||
|
TemporaryFile();
|
||||||
|
~TemporaryFile();
|
||||||
|
|
||||||
|
TemporaryFile(const TemporaryFile&) = delete;
|
||||||
|
TemporaryFile& operator=(const TemporaryFile&) = delete;
|
||||||
|
|
||||||
|
TemporaryFile(TemporaryFile&&) = default;
|
||||||
|
TemporaryFile& operator=(TemporaryFile&&) = default;
|
||||||
|
|
||||||
|
const fs::path& path() const { return path_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
fs::path path_;
|
||||||
|
static fs::path createTemporaryFile();
|
||||||
|
};
|
||||||
|
|
||||||
|
TemporaryFile::TemporaryFile()
|
||||||
|
: path_(createTemporaryFile())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TemporaryFile::~TemporaryFile()
|
||||||
|
{
|
||||||
|
std::error_code ec;
|
||||||
|
fs::remove(path_, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
fs::path TemporaryFile::createTemporaryFile()
|
||||||
|
{
|
||||||
|
char path[] = P_tmpdir "/sndXXXXXX";
|
||||||
|
int fd = mkstemp(path);
|
||||||
|
if (fd == -1)
|
||||||
|
throw std::runtime_error("Cannot create temporary file.");
|
||||||
|
close(fd);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
fs::path TemporaryFile::createTemporaryFile()
|
||||||
|
{
|
||||||
|
DWORD ret = GetTempPathW(0, buffer);
|
||||||
|
std::unique_ptr<WCHAR[]> path;
|
||||||
|
if (ret != 0) {
|
||||||
|
path.reset(new WCHAR[ret + 8]{});
|
||||||
|
ret = GetTempPathW(0, buffer);
|
||||||
|
if (ret != 0)
|
||||||
|
wcscat(path.get(), L"\\XXXXXX");
|
||||||
|
}
|
||||||
|
if (ret == 0 || !_wmktemp(path.get()))
|
||||||
|
throw std::runtime_error("Cannot create temporary file.");
|
||||||
|
return path.get();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///
|
||||||
|
class AudioReaderFixture : public benchmark::Fixture {
|
||||||
|
public:
|
||||||
|
void SetUp(const ::benchmark::State& state) override
|
||||||
|
{
|
||||||
|
workBuffer.resize(2 * static_cast<size_t>(state.range(0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TearDown(const ::benchmark::State& /* state */) override
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static TemporaryFile createAudioFile(int format);
|
||||||
|
|
||||||
|
static TemporaryFile fileWav;
|
||||||
|
static TemporaryFile fileFlac;
|
||||||
|
static TemporaryFile fileOgg;
|
||||||
|
|
||||||
|
std::vector<float> workBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
TemporaryFile AudioReaderFixture::fileWav = createAudioFile(SF_FORMAT_WAV|SF_FORMAT_PCM_16);
|
||||||
|
TemporaryFile AudioReaderFixture::fileFlac = createAudioFile(SF_FORMAT_FLAC|SF_FORMAT_PCM_16);
|
||||||
|
TemporaryFile AudioReaderFixture::fileOgg = createAudioFile(SF_FORMAT_OGG|SF_FORMAT_VORBIS);
|
||||||
|
|
||||||
|
TemporaryFile AudioReaderFixture::createAudioFile(int format)
|
||||||
|
{
|
||||||
|
constexpr unsigned sampleRate = 44100;
|
||||||
|
constexpr unsigned fileDuration = 10;
|
||||||
|
constexpr unsigned fileFrames = sampleRate * fileDuration;
|
||||||
|
|
||||||
|
// synth 2 channels of arbitrary waveform
|
||||||
|
std::unique_ptr<double[]> sndData { new double[2 * fileFrames] };
|
||||||
|
double phase = 0.0;
|
||||||
|
for (unsigned i = 0; i < fileFrames; ++i) {
|
||||||
|
sndData[2 * i ] = std::sin(2.0 * M_PI * phase);
|
||||||
|
sndData[2 * i + 1] = std::cos(2.0 * M_PI * phase);
|
||||||
|
phase += 440.0 * (1.0 / sampleRate);
|
||||||
|
phase -= static_cast<long>(phase);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create temp file
|
||||||
|
TemporaryFile temp;
|
||||||
|
fprintf(stderr, "* Temporary file: %s\n", temp.path().u8string().c_str());
|
||||||
|
|
||||||
|
// write to file
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
SndfileHandle snd(temp.path().c_str(), SFM_WRITE, format, 2, sampleRate);
|
||||||
|
#else
|
||||||
|
SndfileHandle snd(temp.path().wstring().c_str(), SFM_WRITE, format, 2, sampleRate);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (snd.error())
|
||||||
|
throw std::runtime_error("cannot open sound file for writing");
|
||||||
|
snd.writef(sndData.get(), fileFrames);
|
||||||
|
snd = SndfileHandle();
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void doReaderBenchmark(const fs::path& path, std::vector<float> &buffer, sfz::AudioReaderType type)
|
||||||
|
{
|
||||||
|
sfz::AudioReaderPtr reader = sfz::createExplicitAudioReader(path, type);
|
||||||
|
while (reader->readNextBlock(buffer.data(), buffer.size() / 2) > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void doEntireRead(const fs::path& path)
|
||||||
|
{
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
SndfileHandle handle(path.c_str());
|
||||||
|
#else
|
||||||
|
SndfileHandle handle(path.wstring().c_str());
|
||||||
|
#endif
|
||||||
|
if (handle.error())
|
||||||
|
throw std::runtime_error("cannot open sound file for reading");
|
||||||
|
|
||||||
|
std::vector<float> buffer(static_cast<size_t>(2 * handle.frames()));
|
||||||
|
handle.read(buffer.data(), buffer.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(AudioReaderFixture, EntireWav)(benchmark::State& state)
|
||||||
|
{
|
||||||
|
for (auto _ : state) {
|
||||||
|
doEntireRead(fileWav.path());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(AudioReaderFixture, ForwardWav)(benchmark::State& state)
|
||||||
|
{
|
||||||
|
for (auto _ : state) {
|
||||||
|
doReaderBenchmark(fileWav.path(), workBuffer, sfz::AudioReaderType::Forward);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(AudioReaderFixture, ReverseWav)(benchmark::State& state)
|
||||||
|
{
|
||||||
|
for (auto _ : state) {
|
||||||
|
doReaderBenchmark(fileWav.path(), workBuffer, sfz::AudioReaderType::Reverse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(AudioReaderFixture, EntireFlac)(benchmark::State& state)
|
||||||
|
{
|
||||||
|
for (auto _ : state) {
|
||||||
|
doEntireRead(fileFlac.path());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(AudioReaderFixture, ForwardFlac)(benchmark::State& state)
|
||||||
|
{
|
||||||
|
for (auto _ : state) {
|
||||||
|
doReaderBenchmark(fileFlac.path(), workBuffer, sfz::AudioReaderType::Forward);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(AudioReaderFixture, ReverseFlac)(benchmark::State& state)
|
||||||
|
{
|
||||||
|
for (auto _ : state) {
|
||||||
|
doReaderBenchmark(fileFlac.path(), workBuffer, sfz::AudioReaderType::Reverse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(AudioReaderFixture, EntireOgg)(benchmark::State& state)
|
||||||
|
{
|
||||||
|
for (auto _ : state) {
|
||||||
|
doEntireRead(fileOgg.path());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(AudioReaderFixture, ForwardOgg)(benchmark::State& state)
|
||||||
|
{
|
||||||
|
for (auto _ : state) {
|
||||||
|
doReaderBenchmark(fileOgg.path(), workBuffer, sfz::AudioReaderType::Forward);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//BENCHMARK_DEFINE_F(AudioReaderFixture, ReverseOgg)(benchmark::State& state)
|
||||||
|
//{
|
||||||
|
// for (auto _ : state) {
|
||||||
|
// doReaderBenchmark(fileOgg.path(), workBuffer, sfz::AudioReaderType::Reverse);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
BENCHMARK_REGISTER_F(AudioReaderFixture, ForwardWav)->RangeMultiplier(2)->Range((1 << 6), (1 << 10));
|
||||||
|
BENCHMARK_REGISTER_F(AudioReaderFixture, ReverseWav)->RangeMultiplier(2)->Range((1 << 6), (1 << 10));
|
||||||
|
BENCHMARK_REGISTER_F(AudioReaderFixture, EntireWav)->Range(1, 1);
|
||||||
|
BENCHMARK_REGISTER_F(AudioReaderFixture, ForwardFlac)->RangeMultiplier(2)->Range((1 << 6), (1 << 10));
|
||||||
|
BENCHMARK_REGISTER_F(AudioReaderFixture, ReverseFlac)->RangeMultiplier(2)->Range((1 << 6), (1 << 10));
|
||||||
|
BENCHMARK_REGISTER_F(AudioReaderFixture, EntireFlac)->Range(1, 1);
|
||||||
|
BENCHMARK_REGISTER_F(AudioReaderFixture, ForwardOgg)->RangeMultiplier(2)->Range((1 << 6), (1 << 10));
|
||||||
|
//BENCHMARK_REGISTER_F(AudioReaderFixture, ReverseOgg)->RangeMultiplier(2)->Range((1 << 6), (1 << 10));
|
||||||
|
BENCHMARK_REGISTER_F(AudioReaderFixture, EntireOgg)->Range(1, 1);
|
||||||
|
BENCHMARK_MAIN();
|
||||||
52
benchmarks/BM_clamp.cpp
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#include "SIMDHelpers.h"
|
||||||
|
#include "Macros.h"
|
||||||
|
#include <benchmark/benchmark.h>
|
||||||
|
#include <random>
|
||||||
|
#include <numeric>
|
||||||
|
#include <vector>
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class ClampArray : public benchmark::Fixture {
|
||||||
|
public:
|
||||||
|
void SetUp(const ::benchmark::State& state) {
|
||||||
|
std::random_device rd { };
|
||||||
|
std::mt19937 gen { rd() };
|
||||||
|
std::uniform_real_distribution<float> dist { 0, 10 };
|
||||||
|
input = std::vector<float>(state.range(0));
|
||||||
|
std::generate(input.begin(), input.end(), [&]() { return dist(gen); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void TearDown(const ::benchmark::State& state) {
|
||||||
|
UNUSED(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<float> input;
|
||||||
|
};
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(ClampArray, Scalar)(benchmark::State& state) {
|
||||||
|
for (auto _ : state)
|
||||||
|
{
|
||||||
|
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::clampAll, false);
|
||||||
|
sfz::clampAll<float>(absl::MakeSpan(input), 1.2f, 3.8f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(ClampArray, SIMD)(benchmark::State& state) {
|
||||||
|
for (auto _ : state)
|
||||||
|
{
|
||||||
|
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::clampAll, true);
|
||||||
|
sfz::clampAll<float>(absl::MakeSpan(input), 1.2f, 3.8f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BENCHMARK_REGISTER_F(ClampArray, Scalar)->RangeMultiplier(4)->Range(1 << 2, 1 << 12);
|
||||||
|
BENCHMARK_REGISTER_F(ClampArray, SIMD)->RangeMultiplier(4)->Range(1 << 2, 1 << 12);
|
||||||
|
BENCHMARK_MAIN();
|
||||||
|
|
@ -20,7 +20,7 @@ constexpr float sampleRate { 48000.0f };
|
||||||
|
|
||||||
class FilterFixture : public benchmark::Fixture {
|
class FilterFixture : public benchmark::Fixture {
|
||||||
public:
|
public:
|
||||||
void SetUp(const ::benchmark::State& state) {
|
void SetUp(const ::benchmark::State& /* state */) {
|
||||||
inputLeft = std::vector<float>(blockSize);
|
inputLeft = std::vector<float>(blockSize);
|
||||||
inputRight = std::vector<float>(blockSize);
|
inputRight = std::vector<float>(blockSize);
|
||||||
outputLeft = std::vector<float>(blockSize);
|
outputLeft = std::vector<float>(blockSize);
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
class FileFixture : public benchmark::Fixture {
|
class FileFixture : public benchmark::Fixture {
|
||||||
public:
|
public:
|
||||||
void SetUp(const ::benchmark::State& state) {
|
void SetUp(const ::benchmark::State& /* state */) {
|
||||||
filePath1 = getPath() / "sample1.flac";
|
filePath1 = getPath() / "sample1.flac";
|
||||||
filePath2 = getPath() / "sample2.flac";
|
filePath2 = getPath() / "sample2.flac";
|
||||||
filePath3 = getPath() / "sample3.flac";
|
filePath3 = getPath() / "sample3.flac";
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ BENCHMARK_DEFINE_F(MeanSquaredArray, Scalar)
|
||||||
(benchmark::State& state)
|
(benchmark::State& state)
|
||||||
{
|
{
|
||||||
for (auto _ : state) {
|
for (auto _ : state) {
|
||||||
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::meanSquared, false);
|
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::sumSquares, false);
|
||||||
auto result = sfz::meanSquared<float>(input);
|
auto result = sfz::meanSquared<float>(input);
|
||||||
benchmark::DoNotOptimize(result);
|
benchmark::DoNotOptimize(result);
|
||||||
}
|
}
|
||||||
|
|
@ -44,7 +44,7 @@ BENCHMARK_DEFINE_F(MeanSquaredArray, SIMD)
|
||||||
(benchmark::State& state)
|
(benchmark::State& state)
|
||||||
{
|
{
|
||||||
for (auto _ : state) {
|
for (auto _ : state) {
|
||||||
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::meanSquared, true);
|
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::sumSquares, true);
|
||||||
auto result = sfz::meanSquared<float>(input);
|
auto result = sfz::meanSquared<float>(input);
|
||||||
benchmark::DoNotOptimize(result);
|
benchmark::DoNotOptimize(result);
|
||||||
}
|
}
|
||||||
|
|
@ -54,7 +54,7 @@ BENCHMARK_DEFINE_F(MeanSquaredArray, Scalar_Unaligned)
|
||||||
(benchmark::State& state)
|
(benchmark::State& state)
|
||||||
{
|
{
|
||||||
for (auto _ : state) {
|
for (auto _ : state) {
|
||||||
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::meanSquared, false);
|
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::sumSquares, false);
|
||||||
auto result = sfz::meanSquared<float>(absl::MakeSpan(input).subspan(1));
|
auto result = sfz::meanSquared<float>(absl::MakeSpan(input).subspan(1));
|
||||||
benchmark::DoNotOptimize(result);
|
benchmark::DoNotOptimize(result);
|
||||||
}
|
}
|
||||||
|
|
@ -64,7 +64,7 @@ BENCHMARK_DEFINE_F(MeanSquaredArray, SIMD_Unaligned)
|
||||||
(benchmark::State& state)
|
(benchmark::State& state)
|
||||||
{
|
{
|
||||||
for (auto _ : state) {
|
for (auto _ : state) {
|
||||||
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::meanSquared, true);
|
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::sumSquares, true);
|
||||||
auto result = sfz::meanSquared<float>(absl::MakeSpan(input).subspan(1));
|
auto result = sfz::meanSquared<float>(absl::MakeSpan(input).subspan(1));
|
||||||
benchmark::DoNotOptimize(result);
|
benchmark::DoNotOptimize(result);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
83
benchmarks/BM_multiplyMul.cpp
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#include "SIMDHelpers.h"
|
||||||
|
#include <benchmark/benchmark.h>
|
||||||
|
#include <random>
|
||||||
|
#include <numeric>
|
||||||
|
#include <vector>
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class MultiplyMul : public benchmark::Fixture {
|
||||||
|
public:
|
||||||
|
void SetUp(const ::benchmark::State& state) {
|
||||||
|
std::random_device rd { };
|
||||||
|
std::mt19937 gen { rd() };
|
||||||
|
std::uniform_real_distribution<float> dist { 0.1f, 1.0f };
|
||||||
|
input = std::vector<float>(state.range(0));
|
||||||
|
output = std::vector<float>(state.range(0));
|
||||||
|
gain = std::vector<float>(state.range(0));
|
||||||
|
std::fill(output.begin(), output.end(), 2.0f );
|
||||||
|
std::generate(gain.begin(), gain.end(), [&]() { return dist(gen); });
|
||||||
|
std::generate(input.begin(), input.end(), [&]() { return dist(gen); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void TearDown(const ::benchmark::State& /* state */) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<float> gain;
|
||||||
|
std::vector<float> input;
|
||||||
|
std::vector<float> output;
|
||||||
|
};
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(MultiplyMul, Straight)(benchmark::State& state) {
|
||||||
|
for (auto _ : state)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < state.range(0); ++i)
|
||||||
|
output[i] *= gain[i] * input[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(MultiplyMul, Scalar)(benchmark::State& state) {
|
||||||
|
for (auto _ : state)
|
||||||
|
{
|
||||||
|
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyMul, false);
|
||||||
|
sfz::multiplyMul<float>(gain, input, absl::MakeSpan(output));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(MultiplyMul, SIMD)(benchmark::State& state) {
|
||||||
|
for (auto _ : state)
|
||||||
|
{
|
||||||
|
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyMul, true);
|
||||||
|
sfz::multiplyMul<float>(gain, input, absl::MakeSpan(output));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(MultiplyMul, Scalar_Unaligned)(benchmark::State& state) {
|
||||||
|
for (auto _ : state)
|
||||||
|
{
|
||||||
|
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyMul, false);
|
||||||
|
sfz::multiplyMul<float>(absl::MakeSpan(gain).subspan(1), absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(MultiplyMul, SIMD_Unaligned)(benchmark::State& state) {
|
||||||
|
for (auto _ : state)
|
||||||
|
{
|
||||||
|
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyMul, true);
|
||||||
|
sfz::multiplyMul<float>(absl::MakeSpan(gain).subspan(1), absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_REGISTER_F(MultiplyMul, Straight)->RangeMultiplier(4)->Range(1 << 2, 1 << 12);
|
||||||
|
BENCHMARK_REGISTER_F(MultiplyMul, Scalar)->RangeMultiplier(4)->Range(1 << 2, 1 << 12);
|
||||||
|
BENCHMARK_REGISTER_F(MultiplyMul, SIMD)->RangeMultiplier(4)->Range(1 << 2, 1 << 12);
|
||||||
|
BENCHMARK_REGISTER_F(MultiplyMul, Scalar_Unaligned)->RangeMultiplier(4)->Range(1 << 2, 1 << 12);
|
||||||
|
BENCHMARK_REGISTER_F(MultiplyMul, SIMD_Unaligned)->RangeMultiplier(4)->Range(1 << 2, 1 << 12);
|
||||||
|
BENCHMARK_MAIN();
|
||||||
88
benchmarks/BM_multiplyMulFixedGain.cpp
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#include "SIMDHelpers.h"
|
||||||
|
#include <benchmark/benchmark.h>
|
||||||
|
#include <random>
|
||||||
|
#include <numeric>
|
||||||
|
#include <vector>
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class MultiplyMulFixedGain : public benchmark::Fixture {
|
||||||
|
public:
|
||||||
|
void SetUp(const ::benchmark::State& state)
|
||||||
|
{
|
||||||
|
std::random_device rd {};
|
||||||
|
std::mt19937 gen { rd() };
|
||||||
|
std::uniform_real_distribution<float> dist { 0.1f, 1.0f };
|
||||||
|
input = std::vector<float>(state.range(0));
|
||||||
|
output = std::vector<float>(state.range(0));
|
||||||
|
gain = dist(gen);
|
||||||
|
std::fill(output.begin(), output.end(), 2.0f);
|
||||||
|
std::generate(input.begin(), input.end(), [&]() { return dist(gen); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void TearDown(const ::benchmark::State& /* state */)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
float gain = {};
|
||||||
|
std::vector<float> input;
|
||||||
|
std::vector<float> output;
|
||||||
|
};
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(MultiplyMulFixedGain, Straight)
|
||||||
|
(benchmark::State& state)
|
||||||
|
{
|
||||||
|
for (auto _ : state) {
|
||||||
|
for (int i = 0; i < state.range(0); ++i)
|
||||||
|
output[i] *= gain * input[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(MultiplyMulFixedGain, Scalar)
|
||||||
|
(benchmark::State& state)
|
||||||
|
{
|
||||||
|
for (auto _ : state) {
|
||||||
|
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyMul1, false);
|
||||||
|
sfz::multiplyMul1<float>(gain, input, absl::MakeSpan(output));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(MultiplyMulFixedGain, SIMD)
|
||||||
|
(benchmark::State& state)
|
||||||
|
{
|
||||||
|
for (auto _ : state) {
|
||||||
|
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyMul1, true);
|
||||||
|
sfz::multiplyMul1<float>(gain, input, absl::MakeSpan(output));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(MultiplyMulFixedGain, Scalar_Unaligned)
|
||||||
|
(benchmark::State& state)
|
||||||
|
{
|
||||||
|
for (auto _ : state) {
|
||||||
|
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyMul1, false);
|
||||||
|
sfz::multiplyMul1<float>(gain, absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(MultiplyMulFixedGain, SIMD_Unaligned)
|
||||||
|
(benchmark::State& state)
|
||||||
|
{
|
||||||
|
for (auto _ : state) {
|
||||||
|
sfz::setSIMDOpStatus<float>(sfz::SIMDOps::multiplyMul1, true);
|
||||||
|
sfz::multiplyMul1<float>(gain, absl::MakeSpan(input).subspan(1), absl::MakeSpan(output).subspan(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_REGISTER_F(MultiplyMulFixedGain, Straight)->RangeMultiplier(4)->Range(1 << 2, 1 << 12);
|
||||||
|
BENCHMARK_REGISTER_F(MultiplyMulFixedGain, Scalar)->RangeMultiplier(4)->Range(1 << 2, 1 << 12);
|
||||||
|
BENCHMARK_REGISTER_F(MultiplyMulFixedGain, SIMD)->RangeMultiplier(4)->Range(1 << 2, 1 << 12);
|
||||||
|
BENCHMARK_REGISTER_F(MultiplyMulFixedGain, Scalar_Unaligned)->RangeMultiplier(4)->Range(1 << 2, 1 << 12);
|
||||||
|
BENCHMARK_REGISTER_F(MultiplyMulFixedGain, SIMD_Unaligned)->RangeMultiplier(4)->Range(1 << 2, 1 << 12);
|
||||||
|
BENCHMARK_MAIN();
|
||||||
134
benchmarks/BM_pan_arm.cpp
Normal file
|
|
@ -0,0 +1,134 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#include "Panning.h"
|
||||||
|
#include "simd/Common.h"
|
||||||
|
#include <benchmark/benchmark.h>
|
||||||
|
#include <random>
|
||||||
|
#include <absl/algorithm/container.h>
|
||||||
|
#include "absl/types/span.h"
|
||||||
|
#include <arm_neon.h>
|
||||||
|
|
||||||
|
#include <jsl/allocator>
|
||||||
|
template <class T, std::size_t A = 16>
|
||||||
|
using aligned_vector = std::vector<T, jsl::aligned_allocator<T, A>>;
|
||||||
|
|
||||||
|
// Number of elements in the table, odd for equal volume at center
|
||||||
|
constexpr int panSize = 4095;
|
||||||
|
|
||||||
|
// Table of pan values for the left channel, extra element for safety
|
||||||
|
static const auto panData = []()
|
||||||
|
{
|
||||||
|
std::array<float, panSize + 1> pan;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (; i < panSize; ++i)
|
||||||
|
pan[i] = std::cos(i * (piTwo<double>() / (panSize - 1)));
|
||||||
|
|
||||||
|
for (; i < static_cast<int>(pan.size()); ++i)
|
||||||
|
pan[i] = pan[panSize - 1];
|
||||||
|
|
||||||
|
return pan;
|
||||||
|
}();
|
||||||
|
|
||||||
|
float _panLookup(float pan)
|
||||||
|
{
|
||||||
|
// reduce range, round to nearest
|
||||||
|
int index = lroundPositive(pan * (panSize - 1));
|
||||||
|
return panData[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void panScalar(const float* panEnvelope, float* leftBuffer, float* rightBuffer, unsigned size) noexcept
|
||||||
|
{
|
||||||
|
const auto sentinel = panEnvelope + size;
|
||||||
|
while (panEnvelope < sentinel) {
|
||||||
|
auto p =(*panEnvelope + 1.0f) * 0.5f;
|
||||||
|
p = clamp(p, 0.0f, 1.0f);
|
||||||
|
*leftBuffer *= _panLookup(p);
|
||||||
|
*rightBuffer *= _panLookup(1 - p);
|
||||||
|
incrementAll(panEnvelope, leftBuffer, rightBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void panSIMD(const float* panEnvelope, float* leftBuffer, float* rightBuffer, unsigned size) noexcept
|
||||||
|
{
|
||||||
|
const auto sentinel = panEnvelope + size;
|
||||||
|
int32_t indices[4];
|
||||||
|
while (panEnvelope < sentinel) {
|
||||||
|
float32x4_t mmPan = vld1q_f32(panEnvelope);
|
||||||
|
mmPan = vaddq_f32(mmPan, vdupq_n_f32(1.0f));
|
||||||
|
mmPan = vmulq_n_f32(mmPan, 0.5f * panSize);
|
||||||
|
mmPan = vaddq_f32(mmPan, vdupq_n_f32(0.5f));
|
||||||
|
mmPan = vminq_f32(mmPan, vdupq_n_f32(panSize));
|
||||||
|
mmPan = vmaxq_f32(mmPan, vdupq_n_f32(0.0f));
|
||||||
|
int32x4_t mmIdx = vcvtq_s32_f32(mmPan);
|
||||||
|
vst1q_s32(indices, mmIdx);
|
||||||
|
|
||||||
|
leftBuffer[0] *= panData[indices[0]];
|
||||||
|
rightBuffer[0] *= panData[panSize - indices[0] - 1];
|
||||||
|
leftBuffer[1] *= panData[indices[1]];
|
||||||
|
rightBuffer[1] *= panData[panSize - indices[1]- 1];
|
||||||
|
leftBuffer[2] *= panData[indices[2]];
|
||||||
|
rightBuffer[2] *= panData[panSize - indices[2]- 1];
|
||||||
|
leftBuffer[3] *= panData[indices[3]];
|
||||||
|
rightBuffer[3] *= panData[panSize - indices[3]- 1];
|
||||||
|
|
||||||
|
incrementAll<4>(panEnvelope, leftBuffer, rightBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PanFixture : public benchmark::Fixture {
|
||||||
|
public:
|
||||||
|
void SetUp(const ::benchmark::State& state) {
|
||||||
|
std::random_device rd { };
|
||||||
|
std::mt19937 gen { rd() };
|
||||||
|
std::uniform_real_distribution<float> dist { -1.0f, 1.0f };
|
||||||
|
pan.resize(state.range(0));
|
||||||
|
right.resize(state.range(0));
|
||||||
|
left.resize(state.range(0));
|
||||||
|
|
||||||
|
if (!willAlign<16>(pan.data(), left.data(), right.data()))
|
||||||
|
std::cout << "Will not align!" << '\n';
|
||||||
|
absl::c_generate(pan, [&]() { return dist(gen); });
|
||||||
|
absl::c_generate(left, [&]() { return dist(gen); });
|
||||||
|
absl::c_generate(right, [&]() { return dist(gen); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void TearDown(const ::benchmark::State& /* state */) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
aligned_vector<float> pan;
|
||||||
|
aligned_vector<float> right;
|
||||||
|
aligned_vector<float> left;
|
||||||
|
};
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(PanFixture, PanScalar)(benchmark::State& state) {
|
||||||
|
for (auto _ : state)
|
||||||
|
{
|
||||||
|
panScalar(pan.data(), left.data(), right.data(), state.range(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(PanFixture, PanSIMD)(benchmark::State& state) {
|
||||||
|
for (auto _ : state)
|
||||||
|
{
|
||||||
|
panSIMD(pan.data(), left.data(), right.data(), state.range(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(PanFixture, PanSfizz)(benchmark::State& state) {
|
||||||
|
for (auto _ : state)
|
||||||
|
{
|
||||||
|
sfz::pan(pan.data(), left.data(), right.data(), state.range(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register the function as a benchmark
|
||||||
|
BENCHMARK_REGISTER_F(PanFixture, PanScalar)->RangeMultiplier(4)->Range((1 << 4), (1 << 12));
|
||||||
|
BENCHMARK_REGISTER_F(PanFixture, PanSIMD)->RangeMultiplier(4)->Range((1 << 4), (1 << 12));
|
||||||
|
BENCHMARK_REGISTER_F(PanFixture, PanSfizz)->RangeMultiplier(4)->Range((1 << 4), (1 << 12));
|
||||||
|
BENCHMARK_MAIN();
|
||||||
125
benchmarks/BM_powerFollower.cpp
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#include "PowerFollower.h"
|
||||||
|
#include "AudioBuffer.h"
|
||||||
|
#include "Config.h"
|
||||||
|
#include <benchmark/benchmark.h>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
class PowerFollowerFixture : public benchmark::Fixture {
|
||||||
|
public:
|
||||||
|
PowerFollowerFixture()
|
||||||
|
{
|
||||||
|
inputSignal_ = sfz::AudioBuffer<float>(2, numFrames);
|
||||||
|
auto leftSignal = inputSignal_.getSpan(0);
|
||||||
|
auto rightSignal = inputSignal_.getSpan(1);
|
||||||
|
float phase = 0;
|
||||||
|
for (size_t i = 0; i < numFrames; ++i) {
|
||||||
|
constexpr float k2pi = 2.0 * M_PI;
|
||||||
|
leftSignal[i] = std::sin(k2pi * phase);
|
||||||
|
rightSignal[i] = std::cos(k2pi * phase);
|
||||||
|
phase += 440.0f / sfz::config::defaultSampleRate;
|
||||||
|
phase -= static_cast<int>(phase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetUp(const ::benchmark::State& state)
|
||||||
|
{
|
||||||
|
auto blockSize = static_cast<size_t>(state.range(0));
|
||||||
|
follower_.setSampleRate(sfz::config::defaultSampleRate);
|
||||||
|
follower_.setSamplesPerBlock(blockSize);
|
||||||
|
follower_.clear();
|
||||||
|
|
||||||
|
//
|
||||||
|
refFollower_.init(sfz::config::defaultSampleRate);
|
||||||
|
refFollower_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TearDown(const ::benchmark::State& /* state */)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr size_t numFrames = 65536;
|
||||||
|
sfz::PowerFollower follower_;
|
||||||
|
sfz::AudioBuffer<float> inputSignal_;
|
||||||
|
|
||||||
|
//
|
||||||
|
struct ReferenceFollower {
|
||||||
|
/*
|
||||||
|
import("stdfaust.lib");
|
||||||
|
process = (_, _) : + : an.amp_follower_ud(att, rel) with { att = 5e-3; rel = 200e-3; };
|
||||||
|
*/
|
||||||
|
|
||||||
|
void init(float sampleRate)
|
||||||
|
{
|
||||||
|
fConst0 = std::min<float>(192000.0f, std::max<float>(1.0f, float(sampleRate)));
|
||||||
|
fConst1 = std::exp((0.0f - (200.0f / fConst0)));
|
||||||
|
fConst2 = (1.0f - fConst1);
|
||||||
|
fConst3 = std::exp((0.0f - (5.0f / fConst0)));
|
||||||
|
fConst4 = (1.0f - fConst3);
|
||||||
|
}
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
for (int l0 = 0; (l0 < 2); l0 = (l0 + 1)) {
|
||||||
|
fRec1[l0] = 0.0f;
|
||||||
|
}
|
||||||
|
for (int l1 = 0; (l1 < 2); l1 = (l1 + 1)) {
|
||||||
|
fRec0[l1] = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
float process(float input0, float input1)
|
||||||
|
{
|
||||||
|
float fTemp0 = std::fabs((float(input0) + float(input1)));
|
||||||
|
fRec1[0] = std::max<float>(fTemp0, ((fConst3 * fRec1[1]) + (fConst4 * fTemp0)));
|
||||||
|
fRec0[0] = ((fConst1 * fRec0[1]) + (fConst2 * fRec1[0]));
|
||||||
|
float output = fRec0[0];
|
||||||
|
fRec1[1] = fRec1[0];
|
||||||
|
fRec0[1] = fRec0[0];
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
float fConst0;
|
||||||
|
float fConst1;
|
||||||
|
float fConst2;
|
||||||
|
float fConst3;
|
||||||
|
float fConst4;
|
||||||
|
float fRec1[2];
|
||||||
|
float fRec0[2];
|
||||||
|
};
|
||||||
|
ReferenceFollower refFollower_;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr size_t PowerFollowerFixture::numFrames;
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(PowerFollowerFixture, ReferenceFollower) (benchmark::State& state)
|
||||||
|
{
|
||||||
|
sfz::AudioSpan<float> inputSignal(inputSignal_);
|
||||||
|
auto input0 = inputSignal.getConstSpan(0);
|
||||||
|
auto input1 = inputSignal.getConstSpan(1);
|
||||||
|
|
||||||
|
for (auto _ : state) {
|
||||||
|
auto& follower = refFollower_;
|
||||||
|
float output = 0;
|
||||||
|
for (size_t i = 0, n = inputSignal.getNumFrames(); i < n; ++i)
|
||||||
|
output = follower.process(input0[i], input1[i]);
|
||||||
|
benchmark::DoNotOptimize(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_DEFINE_F(PowerFollowerFixture, Follower) (benchmark::State& state)
|
||||||
|
{
|
||||||
|
sfz::AudioSpan<float> inputSignal(inputSignal_);
|
||||||
|
for (auto _ : state) {
|
||||||
|
auto& follower = follower_;
|
||||||
|
auto blockSize = static_cast<size_t>(state.range(0));
|
||||||
|
for (size_t i = 0; i < numFrames; i += blockSize)
|
||||||
|
follower.process(inputSignal.subspan(i, blockSize));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_REGISTER_F(PowerFollowerFixture, ReferenceFollower)->Range(1, 1);
|
||||||
|
BENCHMARK_REGISTER_F(PowerFollowerFixture, Follower)->RangeMultiplier(2)->Range(1 << 5, 1 << 12);
|
||||||
|
|
@ -32,6 +32,7 @@ macro(sfizz_add_benchmark TARGET)
|
||||||
target_link_libraries ("${TARGET}" PRIVATE atomic)
|
target_link_libraries ("${TARGET}" PRIVATE atomic)
|
||||||
endif()
|
endif()
|
||||||
target_include_directories("${TARGET}" PRIVATE ../src/sfizz ../src/external)
|
target_include_directories("${TARGET}" PRIVATE ../src/sfizz ../src/external)
|
||||||
|
sfizz_enable_fast_math("${TARGET}")
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
sfizz_add_benchmark(bm_opf_high_vs_low BM_OPF_high_vs_low.cpp)
|
sfizz_add_benchmark(bm_opf_high_vs_low BM_OPF_high_vs_low.cpp)
|
||||||
|
|
@ -48,6 +49,8 @@ target_link_libraries(bm_ADSR PRIVATE sfizz::sfizz)
|
||||||
sfizz_add_benchmark(bm_add BM_add.cpp)
|
sfizz_add_benchmark(bm_add BM_add.cpp)
|
||||||
sfizz_add_benchmark(bm_multiplyAdd BM_multiplyAdd.cpp)
|
sfizz_add_benchmark(bm_multiplyAdd BM_multiplyAdd.cpp)
|
||||||
sfizz_add_benchmark(bm_multiplyAddFixedGain BM_multiplyAddFixedGain.cpp)
|
sfizz_add_benchmark(bm_multiplyAddFixedGain BM_multiplyAddFixedGain.cpp)
|
||||||
|
sfizz_add_benchmark(bm_multiplyMul BM_multiplyMul.cpp)
|
||||||
|
sfizz_add_benchmark(bm_multiplyMulFixedGain BM_multiplyMulFixedGain.cpp)
|
||||||
sfizz_add_benchmark(bm_subtract BM_subtract.cpp)
|
sfizz_add_benchmark(bm_subtract BM_subtract.cpp)
|
||||||
sfizz_add_benchmark(bm_copy BM_copy.cpp)
|
sfizz_add_benchmark(bm_copy BM_copy.cpp)
|
||||||
sfizz_add_benchmark(bm_mean BM_mean.cpp)
|
sfizz_add_benchmark(bm_mean BM_mean.cpp)
|
||||||
|
|
@ -59,11 +62,15 @@ sfizz_add_benchmark(bm_maps BM_maps.cpp)
|
||||||
target_link_libraries(bm_maps PRIVATE absl::flat_hash_map)
|
target_link_libraries(bm_maps PRIVATE absl::flat_hash_map)
|
||||||
sfizz_add_benchmark(bm_mapVsArray BM_mapVsArray.cpp)
|
sfizz_add_benchmark(bm_mapVsArray BM_mapVsArray.cpp)
|
||||||
sfizz_add_benchmark(bm_random BM_random.cpp)
|
sfizz_add_benchmark(bm_random BM_random.cpp)
|
||||||
|
sfizz_add_benchmark(bm_clamp BM_clamp.cpp)
|
||||||
|
sfizz_add_benchmark(bm_allWithin BM_allWithin.cpp)
|
||||||
|
|
||||||
sfizz_add_benchmark(bm_logger BM_logger.cpp)
|
sfizz_add_benchmark(bm_logger BM_logger.cpp)
|
||||||
target_link_libraries(bm_logger PRIVATE sfizz::sfizz)
|
target_link_libraries(bm_logger PRIVATE sfizz::sfizz)
|
||||||
sfizz_add_benchmark(bm_smoothers BM_smoothers.cpp)
|
sfizz_add_benchmark(bm_smoothers BM_smoothers.cpp)
|
||||||
target_link_libraries(bm_smoothers PRIVATE sfizz::sfizz)
|
target_link_libraries(bm_smoothers PRIVATE sfizz::sfizz)
|
||||||
|
sfizz_add_benchmark(bm_powerFollower BM_powerFollower.cpp)
|
||||||
|
target_link_libraries(bm_powerFollower PRIVATE sfizz::sfizz)
|
||||||
|
|
||||||
if (TARGET sfizz-samplerate)
|
if (TARGET sfizz-samplerate)
|
||||||
sfizz_add_benchmark(bm_resample BM_resample.cpp ${BENCHMARK_SIMD_SOURCES})
|
sfizz_add_benchmark(bm_resample BM_resample.cpp ${BENCHMARK_SIMD_SOURCES})
|
||||||
|
|
@ -78,6 +85,9 @@ target_link_libraries(bm_wavfile PRIVATE sfizz-sndfile)
|
||||||
sfizz_add_benchmark(bm_flacfile BM_flacfile.cpp)
|
sfizz_add_benchmark(bm_flacfile BM_flacfile.cpp)
|
||||||
target_link_libraries(bm_flacfile PRIVATE sfizz-sndfile)
|
target_link_libraries(bm_flacfile PRIVATE sfizz-sndfile)
|
||||||
|
|
||||||
|
sfizz_add_benchmark(bm_audioReaders BM_audioReaders.cpp ../src/sfizz/AudioReader.cpp)
|
||||||
|
target_link_libraries(bm_audioReaders PRIVATE sfizz-sndfile)
|
||||||
|
|
||||||
sfizz_add_benchmark(bm_readChunk BM_readChunk.cpp)
|
sfizz_add_benchmark(bm_readChunk BM_readChunk.cpp)
|
||||||
target_link_libraries(bm_readChunk PRIVATE sfizz-sndfile)
|
target_link_libraries(bm_readChunk PRIVATE sfizz-sndfile)
|
||||||
sfizz_add_benchmark(bm_readChunkFlac BM_readChunkFlac.cpp)
|
sfizz_add_benchmark(bm_readChunkFlac BM_readChunkFlac.cpp)
|
||||||
|
|
@ -137,6 +147,12 @@ if (TARGET bm_resample)
|
||||||
add_dependencies(sfizz_benchmarks bm_resample)
|
add_dependencies(sfizz_benchmarks bm_resample)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (SFIZZ_SYSTEM_PROCESSOR MATCHES "armv7l")
|
||||||
|
sfizz_add_benchmark(bm_pan_arm BM_pan_arm.cpp ../src/sfizz/Panning.cpp)
|
||||||
|
target_link_libraries(bm_pan_arm PRIVATE sfizz-jsl)
|
||||||
|
add_dependencies(sfizz_benchmarks bm_pan_arm)
|
||||||
|
endif()
|
||||||
|
|
||||||
configure_file("sample.wav" "${CMAKE_BINARY_DIR}/benchmarks/sample1.wav" COPYONLY)
|
configure_file("sample.wav" "${CMAKE_BINARY_DIR}/benchmarks/sample1.wav" COPYONLY)
|
||||||
configure_file("sample.wav" "${CMAKE_BINARY_DIR}/benchmarks/sample2.wav" COPYONLY)
|
configure_file("sample.wav" "${CMAKE_BINARY_DIR}/benchmarks/sample2.wav" COPYONLY)
|
||||||
configure_file("sample.wav" "${CMAKE_BINARY_DIR}/benchmarks/sample3.wav" COPYONLY)
|
configure_file("sample.wav" "${CMAKE_BINARY_DIR}/benchmarks/sample3.wav" COPYONLY)
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,11 @@ project (sfizz)
|
||||||
if (SFIZZ_JACK)
|
if (SFIZZ_JACK)
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
pkg_check_modules(JACK "jack" REQUIRED)
|
pkg_check_modules(JACK "jack" REQUIRED)
|
||||||
|
link_directories (${JACK_LIBRARY_DIRS})
|
||||||
|
|
||||||
add_executable (sfizz_jack MidiHelpers.h jack_client.cpp)
|
add_executable (sfizz_jack MidiHelpers.h jack_client.cpp)
|
||||||
target_include_directories (sfizz_jack PRIVATE ${JACK_INCLUDE_DIRS})
|
target_include_directories (sfizz_jack PRIVATE ${JACK_INCLUDE_DIRS})
|
||||||
target_link_libraries (sfizz_jack PRIVATE sfizz::sfizz jack absl::flags_parse ${JACK_LIBRARIES})
|
target_link_libraries (sfizz_jack PRIVATE sfizz::sfizz absl::flags_parse ${JACK_LIBRARIES})
|
||||||
sfizz_enable_lto_if_needed (sfizz_jack)
|
sfizz_enable_lto_if_needed (sfizz_jack)
|
||||||
install (TARGETS sfizz_jack DESTINATION ${CMAKE_INSTALL_BINDIR}
|
install (TARGETS sfizz_jack DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
COMPONENT "jack" OPTIONAL)
|
COMPONENT "jack" OPTIONAL)
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,7 @@
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "sfizz/Synth.h"
|
#include "sfizz.hpp"
|
||||||
#include "sfizz/Macros.h"
|
|
||||||
#include "MidiHelpers.h"
|
#include "MidiHelpers.h"
|
||||||
#include <absl/flags/parse.h>
|
#include <absl/flags/parse.h>
|
||||||
#include <absl/flags/flag.h>
|
#include <absl/flags/flag.h>
|
||||||
|
|
@ -47,9 +46,9 @@ static jack_client_t* client;
|
||||||
|
|
||||||
int process(jack_nframes_t numFrames, void* arg)
|
int process(jack_nframes_t numFrames, void* arg)
|
||||||
{
|
{
|
||||||
auto synth = reinterpret_cast<sfz::Synth*>(arg);
|
auto* synth = reinterpret_cast<sfz::Sfizz*>(arg);
|
||||||
|
|
||||||
auto buffer = jack_port_get_buffer(midiInputPort, numFrames);
|
auto* buffer = jack_port_get_buffer(midiInputPort, numFrames);
|
||||||
assert(buffer);
|
assert(buffer);
|
||||||
|
|
||||||
auto numMidiEvents = jack_midi_get_event_count(buffer);
|
auto numMidiEvents = jack_midi_get_event_count(buffer);
|
||||||
|
|
@ -97,9 +96,11 @@ int process(jack_nframes_t numFrames, void* arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto leftOutput = reinterpret_cast<float*>(jack_port_get_buffer(outputPort1, numFrames));
|
auto* leftOutput = reinterpret_cast<float*>(jack_port_get_buffer(outputPort1, numFrames));
|
||||||
auto rightOutput = reinterpret_cast<float*>(jack_port_get_buffer(outputPort2, numFrames));
|
auto* rightOutput = reinterpret_cast<float*>(jack_port_get_buffer(outputPort2, numFrames));
|
||||||
synth->renderBlock({ { leftOutput, rightOutput }, numFrames });
|
|
||||||
|
float* stereoOutput[] = { leftOutput, rightOutput };
|
||||||
|
synth->renderBlock(stereoOutput, numFrames);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -109,7 +110,7 @@ int sampleBlockChanged(jack_nframes_t nframes, void* arg)
|
||||||
if (arg == nullptr)
|
if (arg == nullptr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto synth = reinterpret_cast<sfz::Synth*>(arg);
|
auto* synth = reinterpret_cast<sfz::Sfizz*>(arg);
|
||||||
// DBG("Sample per block changed to " << nframes);
|
// DBG("Sample per block changed to " << nframes);
|
||||||
synth->setSamplesPerBlock(nframes);
|
synth->setSamplesPerBlock(nframes);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -120,19 +121,19 @@ int sampleRateChanged(jack_nframes_t nframes, void* arg)
|
||||||
if (arg == nullptr)
|
if (arg == nullptr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto synth = reinterpret_cast<sfz::Synth*>(arg);
|
auto* synth = reinterpret_cast<sfz::Sfizz*>(arg);
|
||||||
// DBG("Sample rate changed to " << nframes);
|
// DBG("Sample rate changed to " << nframes);
|
||||||
synth->setSampleRate(nframes);
|
synth->setSampleRate(nframes);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool shouldClose { false };
|
static volatile sig_atomic_t shouldClose { false };
|
||||||
|
|
||||||
static void done(int sig)
|
static void done(int sig)
|
||||||
{
|
{
|
||||||
std::cout << "Signal received" << '\n';
|
std::cout << "Signal received" << '\n';
|
||||||
shouldClose = true;
|
shouldClose = true;
|
||||||
UNUSED(sig);
|
(void)sig;
|
||||||
// if (client != nullptr)
|
// if (client != nullptr)
|
||||||
|
|
||||||
// exit(0);
|
// exit(0);
|
||||||
|
|
@ -163,11 +164,11 @@ int main(int argc, char** argv)
|
||||||
std::cout << "- Oversampling: " << oversampling << '\n';
|
std::cout << "- Oversampling: " << oversampling << '\n';
|
||||||
std::cout << "- Preloaded Size: " << preload_size << '\n';
|
std::cout << "- Preloaded Size: " << preload_size << '\n';
|
||||||
const auto factor = [&]() {
|
const auto factor = [&]() {
|
||||||
if (oversampling == "x1") return sfz::Oversampling::x1;
|
if (oversampling == "x1") return 1;
|
||||||
if (oversampling == "x2") return sfz::Oversampling::x2;
|
if (oversampling == "x2") return 2;
|
||||||
if (oversampling == "x4") return sfz::Oversampling::x4;
|
if (oversampling == "x4") return 4;
|
||||||
if (oversampling == "x8") return sfz::Oversampling::x8;
|
if (oversampling == "x8") return 8;
|
||||||
return sfz::Oversampling::x1;
|
return 1;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
std::cout << "Positional arguments:";
|
std::cout << "Positional arguments:";
|
||||||
|
|
@ -175,7 +176,7 @@ int main(int argc, char** argv)
|
||||||
std::cout << " " << file << ',';
|
std::cout << " " << file << ',';
|
||||||
std::cout << '\n';
|
std::cout << '\n';
|
||||||
|
|
||||||
sfz::Synth synth;
|
sfz::Sfizz synth;
|
||||||
synth.setOversamplingFactor(factor);
|
synth.setOversamplingFactor(factor);
|
||||||
synth.setPreloadSize(preload_size);
|
synth.setPreloadSize(preload_size);
|
||||||
synth.loadSfzFile(filesToParse[0]);
|
synth.loadSfzFile(filesToParse[0]);
|
||||||
|
|
@ -186,6 +187,7 @@ int main(int argc, char** argv)
|
||||||
std::cout << "\tRegions: " << synth.getNumRegions() << '\n';
|
std::cout << "\tRegions: " << synth.getNumRegions() << '\n';
|
||||||
std::cout << "\tCurves: " << synth.getNumCurves() << '\n';
|
std::cout << "\tCurves: " << synth.getNumCurves() << '\n';
|
||||||
std::cout << "\tPreloadedSamples: " << synth.getNumPreloadedSamples() << '\n';
|
std::cout << "\tPreloadedSamples: " << synth.getNumPreloadedSamples() << '\n';
|
||||||
|
#if 0 // not currently in public API
|
||||||
std::cout << "==========" << '\n';
|
std::cout << "==========" << '\n';
|
||||||
std::cout << "Included files:" << '\n';
|
std::cout << "Included files:" << '\n';
|
||||||
for (auto& file : synth.getParser().getIncludedFiles())
|
for (auto& file : synth.getParser().getIncludedFiles())
|
||||||
|
|
@ -194,6 +196,7 @@ int main(int argc, char** argv)
|
||||||
std::cout << "Defines:" << '\n';
|
std::cout << "Defines:" << '\n';
|
||||||
for (auto& define : synth.getParser().getDefines())
|
for (auto& define : synth.getParser().getDefines())
|
||||||
std::cout << '\t' << define.first << '=' << define.second << '\n';
|
std::cout << '\t' << define.first << '=' << define.second << '\n';
|
||||||
|
#endif
|
||||||
std::cout << "==========" << '\n';
|
std::cout << "==========" << '\n';
|
||||||
std::cout << "Unknown opcodes:";
|
std::cout << "Unknown opcodes:";
|
||||||
for (auto& opcode : synth.getUnknownOpcodes())
|
for (auto& opcode : synth.getUnknownOpcodes())
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@ int main(int argc, char** argv)
|
||||||
bool verbose { false };
|
bool verbose { false };
|
||||||
bool help { false };
|
bool help { false };
|
||||||
bool useEOT { false };
|
bool useEOT { false };
|
||||||
|
int quality { 2 };
|
||||||
int oversampling { 1 };
|
int oversampling { 1 };
|
||||||
|
|
||||||
options.add_options()
|
options.add_options()
|
||||||
|
|
@ -74,6 +75,7 @@ int main(int argc, char** argv)
|
||||||
("b,blocksize", "Block size for the sfizz callbacks", cxxopts::value(blockSize))
|
("b,blocksize", "Block size for the sfizz callbacks", cxxopts::value(blockSize))
|
||||||
("s,samplerate", "Output sample rate", cxxopts::value(sampleRate))
|
("s,samplerate", "Output sample rate", cxxopts::value(sampleRate))
|
||||||
("oversampling", "Internal oversampling factor", cxxopts::value(oversampling))
|
("oversampling", "Internal oversampling factor", cxxopts::value(oversampling))
|
||||||
|
("q,quality", "Resampling quality", cxxopts::value(quality))
|
||||||
("v,verbose", "Verbose output", cxxopts::value(verbose))
|
("v,verbose", "Verbose output", cxxopts::value(verbose))
|
||||||
("log", "Produce logs", cxxopts::value<std::string>())
|
("log", "Produce logs", cxxopts::value<std::string>())
|
||||||
("use-eot", "End the rendering at the last End of Track Midi message", cxxopts::value(useEOT))
|
("use-eot", "End the rendering at the last End of Track Midi message", cxxopts::value(useEOT))
|
||||||
|
|
@ -118,6 +120,7 @@ int main(int argc, char** argv)
|
||||||
sfz::Synth synth;
|
sfz::Synth synth;
|
||||||
synth.setSamplesPerBlock(blockSize);
|
synth.setSamplesPerBlock(blockSize);
|
||||||
synth.setSampleRate(sampleRate);
|
synth.setSampleRate(sampleRate);
|
||||||
|
synth.setSampleQuality(sfz::Synth::ProcessMode::ProcessFreewheeling, quality);
|
||||||
synth.enableFreeWheeling();
|
synth.enableFreeWheeling();
|
||||||
|
|
||||||
if (params.count("log") > 0)
|
if (params.count("log") > 0)
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,22 @@ else()
|
||||||
set (LV2PLUGIN_SPDX_LICENSE_ID "ISC")
|
set (LV2PLUGIN_SPDX_LICENSE_ID "ISC")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(SFIZZ_LV2_UI)
|
||||||
|
set(LV2PLUGIN_IF_ENABLE_UI "")
|
||||||
|
else()
|
||||||
|
set(LV2PLUGIN_IF_ENABLE_UI "#")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
set(LV2_UI_TYPE "WindowsUI")
|
||||||
|
elseif(APPLE)
|
||||||
|
set(LV2_UI_TYPE "CocoaUI")
|
||||||
|
elseif(HAIKU)
|
||||||
|
set(LV2_UI_TYPE "BeUI")
|
||||||
|
else()
|
||||||
|
set(LV2_UI_TYPE "X11UI")
|
||||||
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (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}]")
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,31 @@ if (WIN32)
|
||||||
add_compile_definitions(_WIN32_WINNT=0x601)
|
add_compile_definitions(_WIN32_WINNT=0x601)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Set macOS compatibility level
|
||||||
|
if (APPLE)
|
||||||
|
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Do not define macros `min` and `max`
|
||||||
|
if (WIN32)
|
||||||
|
add_compile_definitions(NOMINMAX)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Find macOS system libraries
|
||||||
|
if(APPLE)
|
||||||
|
find_library(APPLE_COREFOUNDATION_LIBRARY "CoreFoundation")
|
||||||
|
find_library(APPLE_FOUNDATION_LIBRARY "Foundation")
|
||||||
|
find_library(APPLE_COCOA_LIBRARY "Cocoa")
|
||||||
|
find_library(APPLE_CARBON_LIBRARY "Carbon")
|
||||||
|
find_library(APPLE_OPENGL_LIBRARY "OpenGL")
|
||||||
|
find_library(APPLE_ACCELERATE_LIBRARY "Accelerate")
|
||||||
|
find_library(APPLE_QUARTZCORE_LIBRARY "QuartzCore")
|
||||||
|
find_library(APPLE_AUDIOTOOLBOX_LIBRARY "AudioToolbox")
|
||||||
|
find_library(APPLE_AUDIOUNIT_LIBRARY "AudioUnit")
|
||||||
|
find_library(APPLE_COREAUDIO_LIBRARY "CoreAudio")
|
||||||
|
find_library(APPLE_COREMIDI_LIBRARY "CoreMIDI")
|
||||||
|
endif()
|
||||||
|
|
||||||
# The variable CMAKE_SYSTEM_PROCESSOR is incorrect on Visual studio...
|
# The variable CMAKE_SYSTEM_PROCESSOR is incorrect on Visual studio...
|
||||||
# see https://gitlab.kitware.com/cmake/cmake/issues/15170
|
# see https://gitlab.kitware.com/cmake/cmake/issues/15170
|
||||||
|
|
||||||
|
|
@ -32,10 +57,15 @@ endif()
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||||
add_compile_options(-Wall)
|
add_compile_options(-Wall)
|
||||||
add_compile_options(-Wextra)
|
add_compile_options(-Wextra)
|
||||||
add_compile_options(-ffast-math)
|
add_compile_options(-Wno-multichar)
|
||||||
add_compile_options(-fno-omit-frame-pointer) # For debugging purposes
|
add_compile_options(-Werror=return-type)
|
||||||
if (SFIZZ_SYSTEM_PROCESSOR MATCHES "^(i.86|x86_64)$")
|
if (SFIZZ_SYSTEM_PROCESSOR MATCHES "^(i.86|x86_64)$")
|
||||||
add_compile_options(-msse2)
|
add_compile_options(-msse2)
|
||||||
|
elseif(SFIZZ_SYSTEM_PROCESSOR MATCHES "^(arm.*)$")
|
||||||
|
add_compile_options(-mfpu=neon)
|
||||||
|
if (NOT ANDROID)
|
||||||
|
add_compile_options(-mfloat-abi=hard)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
@ -43,22 +73,34 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
function(sfizz_enable_fast_math NAME)
|
||||||
|
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||||
|
target_compile_options("${NAME}" PRIVATE "-ffast-math")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# The sndfile library
|
||||||
add_library(sfizz-sndfile INTERFACE)
|
add_library(sfizz-sndfile INTERFACE)
|
||||||
|
|
||||||
|
# The jsl utility library for C++
|
||||||
|
add_library(sfizz-jsl INTERFACE)
|
||||||
|
target_include_directories(sfizz-jsl INTERFACE "external/jsl/include")
|
||||||
|
|
||||||
if (SFIZZ_USE_VCPKG OR CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
if (SFIZZ_USE_VCPKG OR CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||||
find_package(LibSndFile REQUIRED)
|
find_package(SndFile CONFIG REQUIRED)
|
||||||
find_path(SNDFILE_INCLUDE_DIR sndfile.hh)
|
find_path(SNDFILE_INCLUDE_DIR sndfile.hh)
|
||||||
target_include_directories(sfizz-sndfile INTERFACE "${SNDFILE_INCLUDE_DIR}")
|
target_include_directories(sfizz-sndfile INTERFACE "${SNDFILE_INCLUDE_DIR}")
|
||||||
target_link_libraries(sfizz-sndfile INTERFACE sndfile-static)
|
target_link_libraries(sfizz-sndfile INTERFACE SndFile::sndfile)
|
||||||
else()
|
else()
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
pkg_check_modules(SNDFILE "sndfile" REQUIRED)
|
pkg_check_modules(SNDFILE "sndfile" REQUIRED)
|
||||||
target_include_directories(sfizz-sndfile INTERFACE ${SNDFILE_INCLUDE_DIRS})
|
target_include_directories(sfizz-sndfile INTERFACE ${SNDFILE_INCLUDE_DIRS})
|
||||||
if (SFIZZ_STATIC_LIBSNDFILE)
|
if (SFIZZ_STATIC_DEPENDENCIES)
|
||||||
target_link_libraries(sfizz-sndfile INTERFACE ${SNDFILE_STATIC_LIBRARIES})
|
target_link_libraries(sfizz-sndfile INTERFACE ${SNDFILE_STATIC_LIBRARIES})
|
||||||
else()
|
else()
|
||||||
target_link_libraries(sfizz-sndfile INTERFACE ${SNDFILE_LIBRARIES})
|
target_link_libraries(sfizz-sndfile INTERFACE ${SNDFILE_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
link_directories(${SNDFILE_LIBRARY_DIRS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -107,12 +149,13 @@ Build using LTO: ${ENABLE_LTO}
|
||||||
Build as shared library: ${SFIZZ_SHARED}
|
Build as shared library: ${SFIZZ_SHARED}
|
||||||
Build JACK stand-alone client: ${SFIZZ_JACK}
|
Build JACK stand-alone client: ${SFIZZ_JACK}
|
||||||
Build LV2 plug-in: ${SFIZZ_LV2}
|
Build LV2 plug-in: ${SFIZZ_LV2}
|
||||||
|
Build LV2 user interface: ${SFIZZ_LV2_UI}
|
||||||
Build VST plug-in: ${SFIZZ_VST}
|
Build VST plug-in: ${SFIZZ_VST}
|
||||||
Build AU plug-in: ${SFIZZ_AU}
|
Build AU plug-in: ${SFIZZ_AU}
|
||||||
Build benchmarks: ${SFIZZ_BENCHMARKS}
|
Build benchmarks: ${SFIZZ_BENCHMARKS}
|
||||||
Build tests: ${SFIZZ_TESTS}
|
Build tests: ${SFIZZ_TESTS}
|
||||||
Use vcpkg: ${SFIZZ_USE_VCPKG}
|
Use vcpkg: ${SFIZZ_USE_VCPKG}
|
||||||
Statically link libsndfile: ${SFIZZ_STATIC_LIBSNDFILE}
|
Statically link dependencies: ${SFIZZ_STATIC_DEPENDENCIES}
|
||||||
Link libatomic: ${SFIZZ_LINK_LIBATOMIC}
|
Link libatomic: ${SFIZZ_LINK_LIBATOMIC}
|
||||||
Use clang libc++: ${USE_LIBCPP}
|
Use clang libc++: ${USE_LIBCPP}
|
||||||
Release asserts: ${SFIZZ_RELEASE_ASSERTS}
|
Release asserts: ${SFIZZ_RELEASE_ASSERTS}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ macro(sfizz_add_simd_sources SOURCES_VAR PREFIX)
|
||||||
|
|
||||||
list (APPEND ${SOURCES_VAR}
|
list (APPEND ${SOURCES_VAR}
|
||||||
${PREFIX}/sfizz/SIMDHelpers.cpp
|
${PREFIX}/sfizz/SIMDHelpers.cpp
|
||||||
|
${PREFIX}/sfizz/simd/HelpersNEON.cpp
|
||||||
${PREFIX}/sfizz/simd/HelpersSSE.cpp
|
${PREFIX}/sfizz/simd/HelpersSSE.cpp
|
||||||
${PREFIX}/sfizz/simd/HelpersAVX.cpp)
|
${PREFIX}/sfizz/simd/HelpersAVX.cpp)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,10 +30,10 @@ if(NOT VST3_PACKAGE_ARCHITECTURE)
|
||||||
else()
|
else()
|
||||||
set(VST3_PACKAGE_ARCHITECTURE "i386")
|
set(VST3_PACKAGE_ARCHITECTURE "i386")
|
||||||
endif()
|
endif()
|
||||||
elseif(VST3_SYSTEM_PROCESSOR MATCHES "^(armv7l)$")
|
elseif(VST3_SYSTEM_PROCESSOR MATCHES "^(armv[3-8][a-z]*)$")
|
||||||
set(VST3_PACKAGE_ARCHITECTURE "armv7l")
|
set(VST3_PACKAGE_ARCHITECTURE "${VST3_SYSTEM_PROCESSOR}")
|
||||||
elseif(VST3_SYSTEM_PROCESSOR MATCHES "^(aarch64)$")
|
elseif(VST3_SYSTEM_PROCESSOR MATCHES "^(aarch64)$")
|
||||||
set(VST3_PACKAGE_ARCHITECTURE "aarch64")
|
set(VST3_PACKAGE_ARCHITECTURE "aarch64")
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "We don't know this architecture for VST3: ${VST3_SYSTEM_PROCESSOR}.")
|
message(FATAL_ERROR "We don't know this architecture for VST3: ${VST3_SYSTEM_PROCESSOR}.")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
296
common.mk
Normal file
|
|
@ -0,0 +1,296 @@
|
||||||
|
# Common definitions for builds based on GNU Make
|
||||||
|
|
||||||
|
ifndef SFIZZ_DIR
|
||||||
|
$(error sfizz: The source directory must be set before including)
|
||||||
|
endif
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
SFIZZ_MACHINE := $(shell $(CC) -dumpmachine)
|
||||||
|
SFIZZ_PROCESSOR := $(firstword $(subst -, ,$(SFIZZ_MACHINE)))
|
||||||
|
|
||||||
|
ifneq (,$(filter i%86,$(SFIZZ_PROCESSOR)))
|
||||||
|
SFIZZ_CPU_I386 := 1
|
||||||
|
SFIZZ_CPU_I386_OR_X86_64 := 1
|
||||||
|
endif
|
||||||
|
ifneq (,$(filter x86_64,$(SFIZZ_PROCESSOR)))
|
||||||
|
SFIZZ_CPU_X86_64 := 1
|
||||||
|
SFIZZ_CPU_I386_OR_X86_64 := 1
|
||||||
|
endif
|
||||||
|
ifneq (,$(filter arm%,$(SFIZZ_PROCESSOR)))
|
||||||
|
SFIZZ_CPU_ARM := 1
|
||||||
|
SFIZZ_CPU_ARM_OR_AARCH64 := 1
|
||||||
|
endif
|
||||||
|
ifneq (,$(filter aarch64%,$(SFIZZ_PROCESSOR)))
|
||||||
|
SFIZZ_CPU_AARCH64 := 1
|
||||||
|
SFIZZ_CPU_ARM_OR_AARCH64 := 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq (,$(findstring linux,$(SFIZZ_MACHINE)))
|
||||||
|
SFIZZ_OS_LINUX := 1
|
||||||
|
endif
|
||||||
|
ifneq (,$(findstring apple,$(SFIZZ_MACHINE)))
|
||||||
|
SFIZZ_OS_APPLE := 1
|
||||||
|
endif
|
||||||
|
ifneq (,$(findstring mingw,$(SFIZZ_MACHINE)))
|
||||||
|
SFIZZ_OS_WINDOWS := 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
SFIZZ_C_FLAGS = -I$(SFIZZ_DIR)/src
|
||||||
|
SFIZZ_CXX_FLAGS = $(SFIZZ_C_FLAGS)
|
||||||
|
|
||||||
|
SFIZZ_SOURCES = \
|
||||||
|
src/sfizz/ADSREnvelope.cpp \
|
||||||
|
src/sfizz/AudioReader.cpp \
|
||||||
|
src/sfizz/Curve.cpp \
|
||||||
|
src/sfizz/effects/Apan.cpp \
|
||||||
|
src/sfizz/Effects.cpp \
|
||||||
|
src/sfizz/modulations/ModId.cpp \
|
||||||
|
src/sfizz/modulations/ModKey.cpp \
|
||||||
|
src/sfizz/modulations/ModKeyHash.cpp \
|
||||||
|
src/sfizz/modulations/ModMatrix.cpp \
|
||||||
|
src/sfizz/modulations/sources/ADSREnvelope.cpp \
|
||||||
|
src/sfizz/modulations/sources/Controller.cpp \
|
||||||
|
src/sfizz/modulations/sources/FlexEnvelope.cpp \
|
||||||
|
src/sfizz/modulations/sources/LFO.cpp \
|
||||||
|
src/sfizz/effects/Compressor.cpp \
|
||||||
|
src/sfizz/effects/Disto.cpp \
|
||||||
|
src/sfizz/effects/Eq.cpp \
|
||||||
|
src/sfizz/effects/Filter.cpp \
|
||||||
|
src/sfizz/effects/Fverb.cpp \
|
||||||
|
src/sfizz/effects/Gain.cpp \
|
||||||
|
src/sfizz/effects/Gate.cpp \
|
||||||
|
src/sfizz/effects/impl/ResonantArrayAVX.cpp \
|
||||||
|
src/sfizz/effects/impl/ResonantArray.cpp \
|
||||||
|
src/sfizz/effects/impl/ResonantArraySSE.cpp \
|
||||||
|
src/sfizz/effects/impl/ResonantStringAVX.cpp \
|
||||||
|
src/sfizz/effects/impl/ResonantString.cpp \
|
||||||
|
src/sfizz/effects/impl/ResonantStringSSE.cpp \
|
||||||
|
src/sfizz/effects/Limiter.cpp \
|
||||||
|
src/sfizz/effects/Lofi.cpp \
|
||||||
|
src/sfizz/effects/Nothing.cpp \
|
||||||
|
src/sfizz/effects/Rectify.cpp \
|
||||||
|
src/sfizz/effects/Strings.cpp \
|
||||||
|
src/sfizz/effects/Width.cpp \
|
||||||
|
src/sfizz/EQPool.cpp \
|
||||||
|
src/sfizz/FileId.cpp \
|
||||||
|
src/sfizz/FileMetadata.cpp \
|
||||||
|
src/sfizz/FilePool.cpp \
|
||||||
|
src/sfizz/FilterPool.cpp \
|
||||||
|
src/sfizz/FlexEGDescription.cpp \
|
||||||
|
src/sfizz/FlexEnvelope.cpp \
|
||||||
|
src/sfizz/FloatEnvelopes.cpp \
|
||||||
|
src/sfizz/Logger.cpp \
|
||||||
|
src/sfizz/LFO.cpp \
|
||||||
|
src/sfizz/LFODescription.cpp \
|
||||||
|
src/sfizz/MidiState.cpp \
|
||||||
|
src/sfizz/OpcodeCleanup.cpp \
|
||||||
|
src/sfizz/Opcode.cpp \
|
||||||
|
src/sfizz/Oversampler.cpp \
|
||||||
|
src/sfizz/Panning.cpp \
|
||||||
|
src/sfizz/Parser.cpp \
|
||||||
|
src/sfizz/parser/Parser.cpp \
|
||||||
|
src/sfizz/parser/ParserPrivate.cpp \
|
||||||
|
src/sfizz/PolyphonyGroup.cpp \
|
||||||
|
src/sfizz/PowerFollower.cpp \
|
||||||
|
src/sfizz/Region.cpp \
|
||||||
|
src/sfizz/RegionSet.cpp \
|
||||||
|
src/sfizz/RTSemaphore.cpp \
|
||||||
|
src/sfizz/ScopedFTZ.cpp \
|
||||||
|
src/sfizz/sfizz.cpp \
|
||||||
|
src/sfizz/sfizz_wrapper.cpp \
|
||||||
|
src/sfizz/SfzFilter.cpp \
|
||||||
|
src/sfizz/SfzHelpers.cpp \
|
||||||
|
src/sfizz/SIMDHelpers.cpp \
|
||||||
|
src/sfizz/simd/HelpersSSE.cpp \
|
||||||
|
src/sfizz/simd/HelpersAVX.cpp \
|
||||||
|
src/sfizz/Smoothers.cpp \
|
||||||
|
src/sfizz/Synth.cpp \
|
||||||
|
src/sfizz/Tuning.cpp \
|
||||||
|
src/sfizz/utility/SpinMutex.cpp \
|
||||||
|
src/sfizz/Voice.cpp \
|
||||||
|
src/sfizz/VoiceStealing.cpp \
|
||||||
|
src/sfizz/Wavetables.cpp
|
||||||
|
|
||||||
|
### Other internal
|
||||||
|
|
||||||
|
SFIZZ_C_FLAGS += -I$(SFIZZ_DIR)/src/sfizz
|
||||||
|
SFIZZ_C_FLAGS += -I$(SFIZZ_DIR)/src/external
|
||||||
|
|
||||||
|
# Pkg-config dependency
|
||||||
|
|
||||||
|
SFIZZ_PKG_CONFIG ?= pkg-config
|
||||||
|
|
||||||
|
# Sndfile dependency
|
||||||
|
|
||||||
|
SFIZZ_SNDFILE_C_FLAGS ?= $(shell $(SFIZZ_PKG_CONFIG) --cflags sndfile)
|
||||||
|
SFIZZ_SNDFILE_CXX_FLAGS ?= $(SFIZZ_SNDFILE_C_FLAGS)
|
||||||
|
SFIZZ_SNDFILE_LINK_FLAGS ?= $(shell $(SFIZZ_PKG_CONFIG) --libs sndfile)
|
||||||
|
|
||||||
|
SFIZZ_C_FLAGS += $(SFIZZ_SNDFILE_C_FLAGS)
|
||||||
|
SFIZZ_CXX_FLAGS += $(SFIZZ_SNDFILE_CXX_FLAGS)
|
||||||
|
SFIZZ_LINK_FLAGS += $(SFIZZ_SNDFILE_LINK_FLAGS)
|
||||||
|
|
||||||
|
### Abseil dependency
|
||||||
|
|
||||||
|
SFIZZ_C_FLAGS += -I$(SFIZZ_DIR)/external/abseil-cpp
|
||||||
|
# absl::base
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/base/internal/cycleclock.cc \
|
||||||
|
external/abseil-cpp/absl/base/internal/spinlock.cc \
|
||||||
|
external/abseil-cpp/absl/base/internal/sysinfo.cc \
|
||||||
|
external/abseil-cpp/absl/base/internal/thread_identity.cc \
|
||||||
|
external/abseil-cpp/absl/base/internal/unscaledcycleclock.cc
|
||||||
|
# absl::exponential_biased
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/base/internal/exponential_biased.cc
|
||||||
|
# absl::dynamic_annotations
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/base/dynamic_annotations.cc
|
||||||
|
# absl::malloc_internal
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/base/internal/low_level_alloc.cc
|
||||||
|
# absl::raw_logging_internal
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/base/internal/raw_logging.cc
|
||||||
|
# absl::spinlock_wait
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/base/internal/spinlock_wait.cc
|
||||||
|
# absl::throw_delegate
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/base/internal/throw_delegate.cc
|
||||||
|
# absl::strings
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/strings/ascii.cc \
|
||||||
|
external/abseil-cpp/absl/strings/charconv.cc \
|
||||||
|
external/abseil-cpp/absl/strings/escaping.cc \
|
||||||
|
external/abseil-cpp/absl/strings/internal/charconv_bigint.cc \
|
||||||
|
external/abseil-cpp/absl/strings/internal/charconv_parse.cc \
|
||||||
|
external/abseil-cpp/absl/strings/internal/memutil.cc \
|
||||||
|
external/abseil-cpp/absl/strings/match.cc \
|
||||||
|
external/abseil-cpp/absl/strings/numbers.cc \
|
||||||
|
external/abseil-cpp/absl/strings/str_cat.cc \
|
||||||
|
external/abseil-cpp/absl/strings/str_replace.cc \
|
||||||
|
external/abseil-cpp/absl/strings/str_split.cc \
|
||||||
|
external/abseil-cpp/absl/strings/string_view.cc \
|
||||||
|
external/abseil-cpp/absl/strings/substitute.cc
|
||||||
|
# absl::hashtablez_sampler
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/container/internal/hashtablez_sampler.cc \
|
||||||
|
external/abseil-cpp/absl/container/internal/hashtablez_sampler_force_weak_definition.cc
|
||||||
|
# absl::raw_hash_set
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/container/internal/raw_hash_set.cc
|
||||||
|
# absl::synchronization
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/synchronization/barrier.cc \
|
||||||
|
external/abseil-cpp/absl/synchronization/blocking_counter.cc \
|
||||||
|
external/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc \
|
||||||
|
external/abseil-cpp/absl/synchronization/internal/per_thread_sem.cc \
|
||||||
|
external/abseil-cpp/absl/synchronization/internal/waiter.cc \
|
||||||
|
external/abseil-cpp/absl/synchronization/notification.cc \
|
||||||
|
external/abseil-cpp/absl/synchronization/mutex.cc
|
||||||
|
# absl::graphcycles_internal
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/synchronization/internal/graphcycles.cc
|
||||||
|
# absl::time
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/time/civil_time.cc \
|
||||||
|
external/abseil-cpp/absl/time/clock.cc \
|
||||||
|
external/abseil-cpp/absl/time/duration.cc \
|
||||||
|
external/abseil-cpp/absl/time/format.cc \
|
||||||
|
external/abseil-cpp/absl/time/time.cc
|
||||||
|
# absl::time_zone
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc \
|
||||||
|
external/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc \
|
||||||
|
external/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.cc \
|
||||||
|
external/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc \
|
||||||
|
external/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc \
|
||||||
|
external/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc \
|
||||||
|
external/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc \
|
||||||
|
external/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc \
|
||||||
|
external/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc
|
||||||
|
# absl::stacktrace
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/debugging/stacktrace.cc
|
||||||
|
# absl::symbolize
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/debugging/symbolize.cc
|
||||||
|
# absl::demangle_internal
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/debugging/internal/demangle.cc
|
||||||
|
# absl::debugging_internal
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/debugging/internal/address_is_readable.cc \
|
||||||
|
external/abseil-cpp/absl/debugging/internal/elf_mem_image.cc \
|
||||||
|
external/abseil-cpp/absl/debugging/internal/vdso_support.cc
|
||||||
|
# absl::hash
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/hash/internal/hash.cc
|
||||||
|
# absl::city
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/hash/internal/city.cc
|
||||||
|
# absl::int128
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
external/abseil-cpp/absl/numeric/int128.cc
|
||||||
|
|
||||||
|
ifdef SFIZZ_OS_WINDOWS
|
||||||
|
SFIZZ_LINK_FLAGS += -ldbghelp
|
||||||
|
endif
|
||||||
|
|
||||||
|
### Spline dependency
|
||||||
|
|
||||||
|
SFIZZ_C_FLAGS += -I$(SFIZZ_DIR)/src/external/spline
|
||||||
|
SFIZZ_SOURCES += src/external/spline/spline/spline.cpp
|
||||||
|
|
||||||
|
### Cpuid dependency
|
||||||
|
|
||||||
|
SFIZZ_C_FLAGS += \
|
||||||
|
-I$(SFIZZ_DIR)/src/external/cpuid/src \
|
||||||
|
-I$(SFIZZ_DIR)/src/external/cpuid/platform/src
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
src/external/cpuid/src/cpuid/cpuinfo.cpp \
|
||||||
|
src/external/cpuid/src/cpuid/version.cpp
|
||||||
|
|
||||||
|
### Pugixml dependency
|
||||||
|
|
||||||
|
SFIZZ_C_FLAGS += -I$(SFIZZ_DIR)/src/external/pugixml/src
|
||||||
|
SFIZZ_SOURCES += src/external/pugixml/src/pugixml.cpp
|
||||||
|
|
||||||
|
### Kissfft dependency
|
||||||
|
|
||||||
|
SFIZZ_C_FLAGS += \
|
||||||
|
-I$(SFIZZ_DIR)/src/external/kiss_fft \
|
||||||
|
-I$(SFIZZ_DIR)/src/external/kiss_fft/tools
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
src/external/kiss_fft/kiss_fft.c \
|
||||||
|
src/external/kiss_fft/tools/kiss_fftr.c
|
||||||
|
|
||||||
|
### Surge tuning library dependency
|
||||||
|
|
||||||
|
SFIZZ_CXX_FLAGS += \
|
||||||
|
-I$(SFIZZ_DIR)/src/external/tunings/include
|
||||||
|
SFIZZ_SOURCES += \
|
||||||
|
src/external/tunings/src/Tunings.cpp
|
||||||
|
|
||||||
|
### jsl dependency
|
||||||
|
|
||||||
|
SFIZZ_CXX_FLAGS += \
|
||||||
|
-I$(SFIZZ_DIR)/external/jsl/include
|
||||||
|
|
||||||
|
### math dependency
|
||||||
|
|
||||||
|
ifdef SFIZZ_OS_LINUX
|
||||||
|
SFIZZ_LINK_FLAGS += -lm
|
||||||
|
endif
|
||||||
|
|
||||||
|
### pthread dependency
|
||||||
|
|
||||||
|
ifdef SFIZZ_OS_LINUX
|
||||||
|
SFIZZ_C_FLAGS += -pthread
|
||||||
|
SFIZZ_CXX_FLAGS += -pthread
|
||||||
|
SFIZZ_LINK_FLAGS += -pthread
|
||||||
|
endif
|
||||||
|
|
@ -1,187 +0,0 @@
|
||||||
<doxygenlayout version="1.0">
|
|
||||||
<!-- Navigation index tabs for HTML output -->
|
|
||||||
<navindex>
|
|
||||||
<tab type="mainpage" visible="no" title=""/>
|
|
||||||
<tab type="pages" visible="yes" title="" intro=""/>
|
|
||||||
<tab type="modules" visible="yes" title="Categories" intro=""/>
|
|
||||||
<tab type="namespaces" visible="yes" title="">
|
|
||||||
<tab type="namespacelist" visible="yes" title="" intro=""/>
|
|
||||||
<tab type="namespacemembers" visible="yes" title="" intro=""/>
|
|
||||||
</tab>
|
|
||||||
<tab type="classes" visible="yes" title="">
|
|
||||||
<tab type="classlist" visible="yes" title="" intro=""/>
|
|
||||||
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
|
|
||||||
<tab type="hierarchy" visible="yes" title="" intro=""/>
|
|
||||||
<tab type="classmembers" visible="yes" title="" intro=""/>
|
|
||||||
</tab>
|
|
||||||
<tab type="files" visible="yes" title="">
|
|
||||||
<tab type="filelist" visible="yes" title="" intro=""/>
|
|
||||||
<tab type="globals" visible="yes" title="" intro=""/>
|
|
||||||
</tab>
|
|
||||||
<tab type="examples" visible="yes" title="" intro=""/>
|
|
||||||
</navindex>
|
|
||||||
|
|
||||||
<!-- Layout definition for a class page -->
|
|
||||||
<class>
|
|
||||||
<briefdescription visible="no"/>
|
|
||||||
<includes visible="$SHOW_INCLUDE_FILES"/>
|
|
||||||
<inheritancegraph visible="$CLASS_GRAPH"/>
|
|
||||||
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
|
|
||||||
<detaileddescription title=""/>
|
|
||||||
<memberdecl>
|
|
||||||
<membergroups visible="yes"/>
|
|
||||||
<nestedclasses visible="yes" title=""/>
|
|
||||||
<publictypes title=""/>
|
|
||||||
<publicslots title=""/>
|
|
||||||
<signals title=""/>
|
|
||||||
<publicmethods title=""/>
|
|
||||||
<publicstaticmethods title=""/>
|
|
||||||
<publicattributes title=""/>
|
|
||||||
<publicstaticattributes title=""/>
|
|
||||||
<protectedtypes title=""/>
|
|
||||||
<protectedslots title=""/>
|
|
||||||
<protectedmethods title=""/>
|
|
||||||
<protectedstaticmethods title=""/>
|
|
||||||
<protectedattributes title=""/>
|
|
||||||
<protectedstaticattributes title=""/>
|
|
||||||
<packagetypes title=""/>
|
|
||||||
<packagemethods title=""/>
|
|
||||||
<packagestaticmethods title=""/>
|
|
||||||
<packageattributes title=""/>
|
|
||||||
<packagestaticattributes title=""/>
|
|
||||||
<properties title=""/>
|
|
||||||
<events title=""/>
|
|
||||||
<privatetypes title=""/>
|
|
||||||
<privateslots title=""/>
|
|
||||||
<privatemethods title=""/>
|
|
||||||
<privatestaticmethods title=""/>
|
|
||||||
<privateattributes title=""/>
|
|
||||||
<privatestaticattributes title=""/>
|
|
||||||
<friends title=""/>
|
|
||||||
<related title="" subtitle=""/>
|
|
||||||
</memberdecl>
|
|
||||||
<allmemberslink visible="yes"/>
|
|
||||||
<memberdef>
|
|
||||||
<inlineclasses title=""/>
|
|
||||||
<typedefs title=""/>
|
|
||||||
<enums title=""/>
|
|
||||||
<constructors title=""/>
|
|
||||||
<functions title=""/>
|
|
||||||
<related title=""/>
|
|
||||||
<variables title=""/>
|
|
||||||
<properties title=""/>
|
|
||||||
<events title=""/>
|
|
||||||
</memberdef>
|
|
||||||
<usedfiles visible="$SHOW_USED_FILES"/>
|
|
||||||
<authorsection visible="yes"/>
|
|
||||||
</class>
|
|
||||||
|
|
||||||
<!-- Layout definition for a namespace page -->
|
|
||||||
<namespace>
|
|
||||||
<briefdescription visible="no"/>
|
|
||||||
<detaileddescription title=""/>
|
|
||||||
<memberdecl>
|
|
||||||
<membergroups visible="yes"/>
|
|
||||||
<nestednamespaces visible="yes" title=""/>
|
|
||||||
<classes visible="yes" title=""/>
|
|
||||||
<typedefs title=""/>
|
|
||||||
<enums title=""/>
|
|
||||||
<functions title=""/>
|
|
||||||
<variables title=""/>
|
|
||||||
</memberdecl>
|
|
||||||
<memberdef>
|
|
||||||
<inlineclasses title=""/>
|
|
||||||
<typedefs title=""/>
|
|
||||||
<enums title=""/>
|
|
||||||
<functions title=""/>
|
|
||||||
<variables title=""/>
|
|
||||||
</memberdef>
|
|
||||||
<authorsection visible="yes"/>
|
|
||||||
</namespace>
|
|
||||||
|
|
||||||
<!-- Layout definition for a file page -->
|
|
||||||
<file>
|
|
||||||
<briefdescription visible="no"/>
|
|
||||||
<includes visible="$SHOW_INCLUDE_FILES"/>
|
|
||||||
<includegraph visible="$INCLUDE_GRAPH"/>
|
|
||||||
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
|
|
||||||
<sourcelink visible="yes"/>
|
|
||||||
<detaileddescription title=""/>
|
|
||||||
<memberdecl>
|
|
||||||
<membergroups visible="yes"/>
|
|
||||||
<classes visible="yes" title=""/>
|
|
||||||
<namespaces visible="yes" title=""/>
|
|
||||||
<defines title=""/>
|
|
||||||
<typedefs title=""/>
|
|
||||||
<enums title=""/>
|
|
||||||
<functions title=""/>
|
|
||||||
<variables title=""/>
|
|
||||||
</memberdecl>
|
|
||||||
<memberdef>
|
|
||||||
<inlineclasses title=""/>
|
|
||||||
<defines title=""/>
|
|
||||||
<typedefs title=""/>
|
|
||||||
<enums title=""/>
|
|
||||||
<functions title=""/>
|
|
||||||
<variables title=""/>
|
|
||||||
</memberdef>
|
|
||||||
<authorsection/>
|
|
||||||
</file>
|
|
||||||
|
|
||||||
<!-- Layout definition for a group page -->
|
|
||||||
<group>
|
|
||||||
<briefdescription visible="no"/>
|
|
||||||
<groupgraph visible="$GROUP_GRAPHS"/>
|
|
||||||
<detaileddescription title=""/>
|
|
||||||
<memberdecl>
|
|
||||||
<membergroups visible="yes"/>
|
|
||||||
<nestedgroups visible="yes" title=""/>
|
|
||||||
<dirs visible="yes" title=""/>
|
|
||||||
<files visible="yes" title=""/>
|
|
||||||
<namespaces visible="yes" title=""/>
|
|
||||||
<classes visible="yes" title=""/>
|
|
||||||
<defines title=""/>
|
|
||||||
<typedefs title=""/>
|
|
||||||
<enums title=""/>
|
|
||||||
<enumvalues title=""/>
|
|
||||||
<functions title=""/>
|
|
||||||
<variables title=""/>
|
|
||||||
<signals title=""/>
|
|
||||||
<publicslots title=""/>
|
|
||||||
<protectedslots title=""/>
|
|
||||||
<privateslots title=""/>
|
|
||||||
<events title=""/>
|
|
||||||
<properties title=""/>
|
|
||||||
<friends title=""/>
|
|
||||||
</memberdecl>
|
|
||||||
<memberdef>
|
|
||||||
<pagedocs/>
|
|
||||||
<inlineclasses title=""/>
|
|
||||||
<defines title=""/>
|
|
||||||
<typedefs title=""/>
|
|
||||||
<enums title=""/>
|
|
||||||
<enumvalues title=""/>
|
|
||||||
<functions title=""/>
|
|
||||||
<variables title=""/>
|
|
||||||
<signals title=""/>
|
|
||||||
<publicslots title=""/>
|
|
||||||
<protectedslots title=""/>
|
|
||||||
<privateslots title=""/>
|
|
||||||
<events title=""/>
|
|
||||||
<properties title=""/>
|
|
||||||
<friends title=""/>
|
|
||||||
</memberdef>
|
|
||||||
<authorsection visible="yes"/>
|
|
||||||
</group>
|
|
||||||
|
|
||||||
<!-- Layout definition for a directory page -->
|
|
||||||
<directory>
|
|
||||||
<briefdescription visible="yes"/>
|
|
||||||
<directorygraph visible="yes"/>
|
|
||||||
<detaileddescription title=""/>
|
|
||||||
<memberdecl>
|
|
||||||
<dirs visible="yes"/>
|
|
||||||
<files visible="yes"/>
|
|
||||||
</memberdecl>
|
|
||||||
</directory>
|
|
||||||
</doxygenlayout>
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
<hr>
|
|
||||||
<footer>
|
|
||||||
<p style="text-align:left">Copyright © 2019-2020 Paul Ferrand
|
|
||||||
<span style="float:right">Generated for sfizz by
|
|
||||||
<a href="http://www.doxygen.org/index.html"
|
|
||||||
target="_new">Doxygen</a> $doxygenversion</span>
|
|
||||||
</p>
|
|
||||||
</footer>
|
|
||||||
</div><!-- container -->
|
|
||||||
<script src="/sfizz/assets/js/scripts.min.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,155 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
|
|
||||||
<title>Home - sfizz</title>
|
|
||||||
|
|
||||||
<meta name="author" content="Paul Ferrand">
|
|
||||||
<meta name="web-author" content="Andrea Zanellato">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
|
|
||||||
<!-- Atom Feeds -->
|
|
||||||
<link href="/sfizz/atom.xml" rel="alternate" title="News"
|
|
||||||
type="application/atom+xml" />
|
|
||||||
|
|
||||||
<!-- Favicon Generator Icons -->
|
|
||||||
<link rel="apple-touch-icon" sizes="180x180"
|
|
||||||
href="/sfizz/assets/ico/apple-touch-icon.png">
|
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/sfizz/assets/ico/favicon-32x32.png">
|
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/sfizz/assets/ico/favicon-16x16.png">
|
|
||||||
<link rel="manifest" href="/sfizz/assets/ico/site.webmanifest">
|
|
||||||
<link rel="mask-icon" href="/sfizz/assets/ico/safari-pinned-tab.svg"
|
|
||||||
color="#5bbad5">
|
|
||||||
<link rel="shortcut icon" href="/sfizz/assets/ico/favicon.ico">
|
|
||||||
<meta name="msapplication-TileColor"
|
|
||||||
content="#da532c">
|
|
||||||
<meta name="msapplication-config" content="/sfizz/assets/ico/browserconfig.xml">
|
|
||||||
<meta name="theme-color" content="#ffffff">
|
|
||||||
<link href="$relpath$tabs.css" rel="stylesheet" type="text/css"/>
|
|
||||||
<script type="text/javascript" src="$relpath$jquery.js"></script>
|
|
||||||
<script type="text/javascript" src="$relpath$dynsections.js"></script>
|
|
||||||
$treeview
|
|
||||||
$search
|
|
||||||
$mathjax
|
|
||||||
<link href="$relpath$$stylesheet" rel="stylesheet" type="text/css" />
|
|
||||||
$extrastylesheet
|
|
||||||
<!-- Stylesheets -->
|
|
||||||
<link href="/sfizz/assets/css/style.min.css"
|
|
||||||
rel="stylesheet" media="screen">
|
|
||||||
|
|
||||||
<!-- Font Awesome Icons -->
|
|
||||||
<script src="https://kit.fontawesome.com/8d25d19870.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<button onclick="topFunction()" id="scrollButton" title="Go to top">Top</button>
|
|
||||||
<div class="container">
|
|
||||||
<nav class="navbar navbar-expand-lg navbar-dark" style="background-color:#222">
|
|
||||||
<a class="navbar-brand" href="/sfizz/">
|
|
||||||
<img src="/sfizz/assets/img/logo.png"
|
|
||||||
width="30" height="30" class="d-inline-block" alt="">
|
|
||||||
sfizz</a>
|
|
||||||
<button class="navbar-toggler" type="button" data-toggle="collapse"
|
|
||||||
data-target="#navbarContent" aria-controls="navbarContent"
|
|
||||||
aria-expanded="false" aria-label="Toggle navigation">
|
|
||||||
<span class="navbar-toggler-icon"></span>
|
|
||||||
</button>
|
|
||||||
<div class="collapse navbar-collapse" id="navbarContent">
|
|
||||||
<ul class="navbar-nav mr-auto mt-2 mt-lg-0">
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="/">
|
|
||||||
<i class="fas fa-home fa-fw" aria-hidden="true"></i>
|
|
||||||
Home</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<!-- FIXME: Dropdown buttons are shown but menus are broken for some reason
|
|
||||||
(not the container div)
|
|
||||||
|
|
||||||
<li class="nav-item dropdown">
|
|
||||||
<a class="nav-link dropdown-toggle" href="#"
|
|
||||||
id="navbarProjects" data-toggle="dropdown"
|
|
||||||
aria-haspopup="true" aria-expanded="false">
|
|
||||||
<i class="fas fa-hammer fa-fw" aria-hidden="true"></i>
|
|
||||||
Projects</a>
|
|
||||||
<div class="dropdown-menu" aria-labelledby="navbarProjects">
|
|
||||||
<a class="dropdown-item"
|
|
||||||
href="/beatbox/">
|
|
||||||
<i class="fas fa-drum fa-fw" aria-hidden="true"></i>
|
|
||||||
BeatBox</a>
|
|
||||||
<a class="dropdown-item disabled"
|
|
||||||
href="/sfizz/">
|
|
||||||
<i class="fas fa-play-circle fa-fw" aria-hidden="true"></i>
|
|
||||||
sfizz</a>
|
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<a class="dropdown-item"
|
|
||||||
href="https://github.com/sfztools/sfizz-render/">
|
|
||||||
sfizz-render</a>
|
|
||||||
<a class="dropdown-item"
|
|
||||||
href="https://github.com/sfztools/sfz-flat/">
|
|
||||||
sfz-flat</a>
|
|
||||||
<a class="dropdown-item"
|
|
||||||
href="https://github.com/sfztools/sfz-opcode-checker/">
|
|
||||||
sfz-opcode-checker</a>
|
|
||||||
<div class="dropdown-divider"></div>
|
|
||||||
<a class="dropdown-item"
|
|
||||||
href="https://github.com/sfztools/emacs-sfz-mode/">
|
|
||||||
Emacs Syntax Highlight</a>
|
|
||||||
<a class="dropdown-item"
|
|
||||||
href="https://github.com/sfztools/syntax-highlighting-gedit/">
|
|
||||||
gedit Syntax Highlight</a>
|
|
||||||
<a class="dropdown-item"
|
|
||||||
href="https://github.com/sfztools/syntax-highlighting-geany/">
|
|
||||||
Geany Syntax Highlight</a>
|
|
||||||
<a class="dropdown-item"
|
|
||||||
href="https://github.com/sfztools/syntax-highlighting-sublime-text/">
|
|
||||||
Sublime Text Syntax Highlight</a>
|
|
||||||
<a class="dropdown-item"
|
|
||||||
href="https://github.com/sfztools/sfz.vim">
|
|
||||||
Vim Syntax Highlight</a>
|
|
||||||
<a class="dropdown-item"
|
|
||||||
href="https://github.com/sfztools/syntax-highlighting-vscode/">
|
|
||||||
VSCode Syntax Highlight</a>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item dropdown">
|
|
||||||
<a class="nav-link dropdown-toggle" href="#"
|
|
||||||
id="navbarDocumentation" data-toggle="dropdown"
|
|
||||||
aria-haspopup="true" aria-expanded="false">
|
|
||||||
<i class="fas fa-book fa-fw" aria-hidden="true"></i>
|
|
||||||
Documentation</a>
|
|
||||||
<div class="dropdown-menu" aria-labelledby="navbarDocumentation">
|
|
||||||
<a class="dropdown-item"
|
|
||||||
href="/sfizz/api"><i class="fas fa-code fa-fw" aria-hidden="true"></i>
|
|
||||||
API</a>
|
|
||||||
<a class="dropdown-item"
|
|
||||||
href="/sfizz/development/build">
|
|
||||||
<i class="fas fa-code fa-fw" aria-hidden="true"></i>
|
|
||||||
Build</a>
|
|
||||||
<a class="dropdown-item"
|
|
||||||
href="/sfizz/development/status">
|
|
||||||
<i class="fas fa-tasks fa-fw" aria-hidden="true"></i>
|
|
||||||
SFZ Opcodes</a>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
-->
|
|
||||||
</ul>
|
|
||||||
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="/sfizz/downloads">
|
|
||||||
<i class="fas fa-download fa-fw" aria-hidden="true"></i>
|
|
||||||
Download</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="/sfizz/search/">
|
|
||||||
<i class="fas fa-search fa-fw" aria-hidden="true"></i>
|
|
||||||
Search</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<!--BEGIN DISABLE_INDEX-->
|
|
||||||
<!--BEGIN SEARCHENGINE-->
|
|
||||||
$searchbox
|
|
||||||
<!--END SEARCHENGINE-->
|
|
||||||
<!--END DISABLE_INDEX-->
|
|
||||||
</nav>
|
|
||||||
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
|
||||||
|
|
@ -1,198 +0,0 @@
|
||||||
#page_container {
|
|
||||||
position: relative;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
height: auto !important;
|
|
||||||
height: 100%;
|
|
||||||
min-height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.contents, div.searchresults {
|
|
||||||
margin-top: 10px;
|
|
||||||
margin-right: 12px;
|
|
||||||
padding-bottom: 70px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#projectlogo {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
#projectnumber {
|
|
||||||
font-size: 120%;
|
|
||||||
font-family: Tahoma, Arial, sans-serif;
|
|
||||||
text-align: right;
|
|
||||||
padding: 0.5em 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tabs {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.tabs2, .tabs3 {
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navpath ul {
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1, h2, h3, h4, h5, h6 {
|
|
||||||
color: #002D88;
|
|
||||||
font-weight: normal;
|
|
||||||
margin-top: 1em;
|
|
||||||
margin-bottom: 0.5em;
|
|
||||||
padding-top: 8px;
|
|
||||||
padding-bottom: 4px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 150%;
|
|
||||||
border-bottom: 1px solid #3276FF;
|
|
||||||
}
|
|
||||||
h2 {
|
|
||||||
font-size: 135%;
|
|
||||||
margin-top: 0.75em;
|
|
||||||
}
|
|
||||||
h3 {
|
|
||||||
font-size: 120%;
|
|
||||||
margin-top: 0.5em;
|
|
||||||
}
|
|
||||||
h4 {
|
|
||||||
font-size: 100%;
|
|
||||||
margin-top: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.headertitle h1 {
|
|
||||||
margin: 10px 2px;
|
|
||||||
border: none;
|
|
||||||
padding: 0;
|
|
||||||
width: auto;
|
|
||||||
color: black;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.toc h3 {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.toc li {
|
|
||||||
font-size: 12px;
|
|
||||||
line-height: 1.3;
|
|
||||||
padding-left: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
img.logo {
|
|
||||||
float: right;
|
|
||||||
margin: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.logo {
|
|
||||||
float: right;
|
|
||||||
margin: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.directory {
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
line-height: 1.25;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.appearance {
|
|
||||||
margin: 1em 0em;
|
|
||||||
}
|
|
||||||
div.appearance table {
|
|
||||||
margin: 0.5em 0em;
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
div.appearance img {
|
|
||||||
margin: 0.5em;
|
|
||||||
}
|
|
||||||
div.appearance .caption {
|
|
||||||
font-style: italic;
|
|
||||||
font-weight: normal;
|
|
||||||
font-size: 90%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.appearance_brief table {
|
|
||||||
width: 100%;
|
|
||||||
table-layout: fixed;
|
|
||||||
text-align: center;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.appearance_brief table td:first-child {
|
|
||||||
width: 20em;
|
|
||||||
text-align: left;
|
|
||||||
padding-left: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.appearance_brief table td {
|
|
||||||
border-style: none solid solid none;
|
|
||||||
border-width: 1px;
|
|
||||||
border-color: lightblue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
td.green { color: green; }
|
|
||||||
td.orange { color: #ff8000; }
|
|
||||||
td.red { color: red; }
|
|
||||||
|
|
||||||
span.literal {
|
|
||||||
text-decoration: none;
|
|
||||||
font-weight: bold;
|
|
||||||
font-family: monospace, fixed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we make all the following <span> tags render the text just like
|
|
||||||
the standard Doxygen @remarks, @see tags do, to obtain a uniform
|
|
||||||
look and feel */
|
|
||||||
span.itemdef, span.lib, span.category, span.stdobj, span.styles,
|
|
||||||
span.events, span.flags, span.appearance, span.impl, span.avail {
|
|
||||||
font-weight: bold;
|
|
||||||
line-height: 130%;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.style, span.event, span.flag {
|
|
||||||
font-weight: bold;
|
|
||||||
color: #880000;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.styleDesc, div.eventDesc, div.flagDesc {
|
|
||||||
margin-left: 3%;
|
|
||||||
margin-bottom: 1ex;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.eventHandler {
|
|
||||||
margin: 1em;
|
|
||||||
text-indent: 3%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.eventHandler span {
|
|
||||||
padding: 5px;
|
|
||||||
background-color: #eeeeee;
|
|
||||||
font-family: monospace, fixed;
|
|
||||||
}
|
|
||||||
|
|
||||||
code {
|
|
||||||
font-size: 110%;
|
|
||||||
color: #444444;
|
|
||||||
}
|
|
||||||
|
|
||||||
address.footer {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
margin: 0;
|
|
||||||
padding: 10px 0;
|
|
||||||
width: 100%;
|
|
||||||
border-top: 1px solid #0043CC;
|
|
||||||
background-image: url('nav_h.png');
|
|
||||||
background-repeat: repeat-x;
|
|
||||||
background-color: #F4F8FF;
|
|
||||||
}
|
|
||||||
|
|
||||||
address.footer small {
|
|
||||||
padding: 0 10px;
|
|
||||||
}
|
|
||||||
|
|
@ -1,154 +0,0 @@
|
||||||
# Global view of the engine
|
|
||||||
|
|
||||||
The sfizz engine is basically a "Synth" object that takes an SFZ file in, receives MIDI-type events
|
|
||||||
and is able to render audio through successive calls to a callback function. This is in line with
|
|
||||||
the way most audio applications and plugins are working. A high-level overview is presented in the
|
|
||||||
following diagram.
|
|
||||||
|
|
||||||
```
|
|
||||||
C and C++ API entry point
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
+--------v-------+
|
|
||||||
| |
|
|
||||||
+-------------------------- Synth -----------------------------+
|
|
||||||
| | | |
|
|
||||||
| +----------------+ |
|
|
||||||
| | |
|
|
||||||
+--------v------+ | +---------v--------+
|
|
||||||
| | +---------v---------+ | |
|
|
||||||
| Region list | | Common resources | | Voice pool |
|
|
||||||
| | | and state | | |
|
|
||||||
+---------------+ | ----------------- | +------------------+
|
|
||||||
Built from the SFZ file | File pool |
|
|
||||||
| Envelope pool | The voices are the polyphony
|
|
||||||
Each region is a semi-passive | LFO pool | of the synth. They are idle
|
|
||||||
description object that can | Buffer pool | and they get activated by the
|
|
||||||
decide whether it is "active" | Midi state | synth to play a region on a
|
|
||||||
or not depending on the chain | ... | specific event. They are then
|
|
||||||
of MIDI events it receives. +-------------------+ "linked" to the region while
|
|
||||||
Once activated, a voice is There are a number of common it is played, and reset to
|
|
||||||
chosen to play the region until resources that are needed for their idle state when they
|
|
||||||
it ends naturally or through all the regions and in parti- are done playing the region.
|
|
||||||
note-offs or off-groups. cular the voices. This includes
|
|
||||||
all the (preloaded) files for
|
|
||||||
the SFZ instrument, but will
|
|
||||||
include in the future the EG
|
|
||||||
and LFOs that are needed to
|
|
||||||
achieve compliance with the
|
|
||||||
SFZ v2 specification. This will
|
|
||||||
also include a temporary buffer
|
|
||||||
holder that voices may share.
|
|
||||||
A common resource of importance
|
|
||||||
is the MIDI state: note durations
|
|
||||||
are needed for some opcodes --
|
|
||||||
for example rt_decay -- and
|
|
||||||
triggering velocities too.
|
|
||||||
```
|
|
||||||
|
|
||||||
The Synth, Voices and Regions form the bulk of the code complexity. The rest of the engine is dedicated of
|
|
||||||
mostly helper classes to enable easy management of floating-point buffers in which the audio data is held,
|
|
||||||
signal processing and accelerated (SIMD) computations, and abstractions that are specific to the SFZ format
|
|
||||||
such as envelope generators, curves or LFOs.
|
|
||||||
|
|
||||||
# Parsing the SFZ files
|
|
||||||
|
|
||||||
The sfz file logic is pretty simple and well defined. The sfzformat.com website contains an extensive documentation
|
|
||||||
on it. At its core, an SFZ file describes a list of `region` objects on which a certain number of "opcodes" will
|
|
||||||
apply. Opcodes can determine the sample played, the event conditions that will trigger the sample such as the range
|
|
||||||
of notes, channels, velocities, the processing to apply on the sample while playing, and many more things. It is
|
|
||||||
also possible to describe a `group` of regions, as well as exclusive groups that will shut off other regions that may
|
|
||||||
already be playing. There are also `master` groups, and `global` opcodes and some other types.
|
|
||||||
|
|
||||||
All the opcodes are declared within a header, in a pseudo-xml markup language that looks like this
|
|
||||||
```sfz
|
|
||||||
<global> volume=6
|
|
||||||
<control> set_cc4=5
|
|
||||||
<region> key=36 sample=kick.wav
|
|
||||||
```
|
|
||||||
Here we have 3 headers (`global`, `control` and `region`) and each header holds some opcodes. All of these opcodes
|
|
||||||
have a value---for example the volume is equal to 6 in the `global` header. Some opcodes also have parameters.
|
|
||||||
The `control` header holds an opcode `set_cc` with the parameter `4` and value `5`. The parameter here is the CC to set,
|
|
||||||
and the value at which to set it is 5.
|
|
||||||
|
|
||||||
The parsing logic of sfizz is handled through a base class called Parser---a very original choice. This parser has
|
|
||||||
a virtual callback that gets called whenever a header description is "complete", along with a list of opcodes that
|
|
||||||
apply to the header. Subclassing the Parser then allows to build different SFZ handlers, from full-blown synths as
|
|
||||||
with sfizz to simpler things such as printers (see in particular https://github.com/sfztools/sfz-flat/). If we look
|
|
||||||
at the core of the latter example, it will look something like the following
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
class PrintingParser: public sfz::Parser
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
void callback(absl::string_view header, const std::vector<sfz::Opcode>& members) final
|
|
||||||
{
|
|
||||||
switch (hash(header)) // The hash(...) function transforms strings to large integers
|
|
||||||
{
|
|
||||||
case hash("global"): // It is also compile-time defined, which allows to do switch-case
|
|
||||||
// statements on strings, something that is usually not possible
|
|
||||||
globalMembers = members; // We save the global headers since they apply to the next
|
|
||||||
// region (and groups and masters)
|
|
||||||
masterMembers.clear();
|
|
||||||
groupMembers.clear();
|
|
||||||
break;
|
|
||||||
case hash("master"):
|
|
||||||
masterMembers = members; // So on
|
|
||||||
groupMembers.clear();
|
|
||||||
break;
|
|
||||||
case hash("group"):
|
|
||||||
groupMembers = members; // .. and so forth
|
|
||||||
break;
|
|
||||||
case hash("region"):
|
|
||||||
std::cout << "<" << header << ">" << ' '; // Now we print the region along with all the opcodes
|
|
||||||
// we memorized from earlier headers.
|
|
||||||
printMembers(globalMembers);
|
|
||||||
printMembers(masterMembers);
|
|
||||||
printMembers(groupMembers);
|
|
||||||
printMembers(members);
|
|
||||||
std::cout << '\n';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
std::cout << "<" << header << ">" << ' ';
|
|
||||||
printMembers(members);
|
|
||||||
std::cout << '\n';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
std::vector<sfz::Opcode> globalMembers;
|
|
||||||
std::vector<sfz::Opcode> masterMembers;
|
|
||||||
std::vector<sfz::Opcode> groupMembers;
|
|
||||||
void printMembers(const std::vector<sfz::Opcode>& members)
|
|
||||||
{
|
|
||||||
for (auto& member: members)
|
|
||||||
{
|
|
||||||
std::cout << member.opcode;
|
|
||||||
if (member.parameter)
|
|
||||||
std::cout << +*member.parameter;
|
|
||||||
std::cout << "=" << member.value;
|
|
||||||
std::cout << ' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
The main function is then quite straightforward and we call a function from the Parser class that loads a file
|
|
||||||
```cpp
|
|
||||||
PrintingParser parser;
|
|
||||||
parser.loadSfzFile("my_sfz_file.sfz");
|
|
||||||
```
|
|
||||||
If you circle back to the parser you will see that opcodes are stored in an `Opcode` class. This class does some parsing
|
|
||||||
itself and separates the opcode name itself, parameters if any, and the value. Opcodes are very cheap to copy and pass
|
|
||||||
around because they only refer to characters in the file that are stored inside the `Parser` class, so feel free to
|
|
||||||
create vectors of them and move them around.
|
|
||||||
|
|
||||||
Note that you may also derive the loadSfzFile method if you have any processing you need to do before the actual parsing happens.
|
|
||||||
|
|
||||||
# Building the region list in sfizz
|
|
||||||
|
|
||||||
The callback method from sfizz is actually quite similar to the one shown above, except that instead of printing the region
|
|
||||||
we actually fill a big structure from it.
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# sfizz
|
|
||||||
|
|
||||||
SFZ file format library
|
|
||||||
|
|
||||||
- [public C API](sfizz_8h.html)
|
|
||||||
- [public C++ API](classsfz_1_1_sfizz.html)
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# Must be called from the root directory
|
|
||||||
if [[ -f api_index.md ]]; then rm api_index.md; fi
|
|
||||||
cat >>api_index.md <<EOF
|
|
||||||
---
|
|
||||||
title: "API"
|
|
||||||
---
|
|
||||||
EOF
|
|
||||||
tags=()
|
|
||||||
for tag in $(git tag --list); do
|
|
||||||
if [[ ${tag} != "list" && ${tag} != *"test"* ]]; then
|
|
||||||
tag=$(echo "${tag}" | sed -r 's/v//g')
|
|
||||||
tags+=("${tag}")
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
IFS=$'\n' tags=($(sort <<<"${tags[*]}")); unset IFS
|
|
||||||
for tag in "${tags[@]}"; do
|
|
||||||
echo "- [${tag}](${tag})" >> api_index.md
|
|
||||||
done
|
|
||||||
202
dpf.mk
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
#
|
#
|
||||||
# A build file to help using sfizz with the DISTRHO Plugin Framework (DPF)
|
# A build file to help using sfizz with the DISTRHO Plugin Framework (DPF)
|
||||||
# ------------------------------------------------------------------------
|
# ------------------------------------------------------------------------
|
||||||
|
|
@ -36,14 +37,9 @@
|
||||||
|
|
||||||
SFIZZ_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
|
SFIZZ_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
|
||||||
SFIZZ_BUILD_DIR := $(SFIZZ_DIR)/dpf-build
|
SFIZZ_BUILD_DIR := $(SFIZZ_DIR)/dpf-build
|
||||||
|
|
||||||
SFIZZ_C_FLAGS = -I$(SFIZZ_DIR)/src
|
|
||||||
SFIZZ_CXX_FLAGS = $(SFIZZ_C_FLAGS)
|
|
||||||
SFIZZ_LINK_FLAGS = $(SFIZZ_BUILD_DIR)/libsfizz.a
|
SFIZZ_LINK_FLAGS = $(SFIZZ_BUILD_DIR)/libsfizz.a
|
||||||
|
SFIZZ_PKG_CONFIG ?= $(PKG_CONFIG)
|
||||||
ifeq ($(LINUX),true)
|
include $(SFIZZ_DIR)/common.mk
|
||||||
SFIZZ_LINK_FLAGS += -pthread
|
|
||||||
endif
|
|
||||||
|
|
||||||
sfizz-all: sfizz-lib
|
sfizz-all: sfizz-lib
|
||||||
|
|
||||||
|
|
@ -54,198 +50,6 @@ sfizz-clean:
|
||||||
|
|
||||||
.PHONY: sfizz-all sfizz-lib sfizz-clean
|
.PHONY: sfizz-all sfizz-lib sfizz-clean
|
||||||
|
|
||||||
SFIZZ_SOURCES = \
|
|
||||||
src/sfizz/ADSREnvelope.cpp \
|
|
||||||
src/sfizz/Curve.cpp \
|
|
||||||
src/sfizz/effects/Apan.cpp \
|
|
||||||
src/sfizz/Effects.cpp \
|
|
||||||
src/sfizz/effects/Eq.cpp \
|
|
||||||
src/sfizz/effects/Filter.cpp \
|
|
||||||
src/sfizz/effects/Gain.cpp \
|
|
||||||
src/sfizz/effects/impl/ResonantArrayAVX.cpp \
|
|
||||||
src/sfizz/effects/impl/ResonantArray.cpp \
|
|
||||||
src/sfizz/effects/impl/ResonantArraySSE.cpp \
|
|
||||||
src/sfizz/effects/impl/ResonantStringAVX.cpp \
|
|
||||||
src/sfizz/effects/impl/ResonantString.cpp \
|
|
||||||
src/sfizz/effects/impl/ResonantStringSSE.cpp \
|
|
||||||
src/sfizz/effects/Limiter.cpp \
|
|
||||||
src/sfizz/effects/Lofi.cpp \
|
|
||||||
src/sfizz/effects/Nothing.cpp \
|
|
||||||
src/sfizz/effects/Rectify.cpp \
|
|
||||||
src/sfizz/effects/Strings.cpp \
|
|
||||||
src/sfizz/effects/Width.cpp \
|
|
||||||
src/sfizz/EQPool.cpp \
|
|
||||||
src/sfizz/FileId.cpp \
|
|
||||||
src/sfizz/FileInstrument.cpp \
|
|
||||||
src/sfizz/FilePool.cpp \
|
|
||||||
src/sfizz/FilterPool.cpp \
|
|
||||||
src/sfizz/FloatEnvelopes.cpp \
|
|
||||||
src/sfizz/Logger.cpp \
|
|
||||||
src/sfizz/MidiState.cpp \
|
|
||||||
src/sfizz/OpcodeCleanup.cpp \
|
|
||||||
src/sfizz/Opcode.cpp \
|
|
||||||
src/sfizz/Oversampler.cpp \
|
|
||||||
src/sfizz/Panning.cpp \
|
|
||||||
src/sfizz/Parser.cpp \
|
|
||||||
src/sfizz/parser/Parser.cpp \
|
|
||||||
src/sfizz/parser/ParserPrivate.cpp \
|
|
||||||
src/sfizz/Region.cpp \
|
|
||||||
src/sfizz/RTSemaphore.cpp \
|
|
||||||
src/sfizz/ScopedFTZ.cpp \
|
|
||||||
src/sfizz/sfizz.cpp \
|
|
||||||
src/sfizz/sfizz_wrapper.cpp \
|
|
||||||
src/sfizz/SfzFilter.cpp \
|
|
||||||
src/sfizz/SfzHelpers.cpp \
|
|
||||||
src/sfizz/SIMDHelpers.cpp \
|
|
||||||
src/sfizz/simd/HelpersSSE.cpp \
|
|
||||||
src/sfizz/simd/HelpersAVX.cpp \
|
|
||||||
src/sfizz/Synth.cpp \
|
|
||||||
src/sfizz/Tuning.cpp \
|
|
||||||
src/sfizz/Voice.cpp \
|
|
||||||
src/sfizz/Wavetables.cpp
|
|
||||||
|
|
||||||
### Other internal
|
|
||||||
|
|
||||||
SFIZZ_C_FLAGS += -I$(SFIZZ_DIR)/src/sfizz
|
|
||||||
SFIZZ_C_FLAGS += -I$(SFIZZ_DIR)/src/external
|
|
||||||
|
|
||||||
# Sndfile dependency
|
|
||||||
|
|
||||||
SFIZZ_C_FLAGS += $(shell $(PKG_CONFIG) --cflags sndfile)
|
|
||||||
SFIZZ_LINK_FLAGS += $(shell $(PKG_CONFIG) --libs sndfile)
|
|
||||||
|
|
||||||
### Abseil dependency
|
|
||||||
|
|
||||||
SFIZZ_C_FLAGS += -I$(SFIZZ_DIR)/external/abseil-cpp
|
|
||||||
# absl::base
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/base/internal/cycleclock.cc \
|
|
||||||
external/abseil-cpp/absl/base/internal/spinlock.cc \
|
|
||||||
external/abseil-cpp/absl/base/internal/sysinfo.cc \
|
|
||||||
external/abseil-cpp/absl/base/internal/thread_identity.cc \
|
|
||||||
external/abseil-cpp/absl/base/internal/unscaledcycleclock.cc
|
|
||||||
# absl::exponential_biased
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/base/internal/exponential_biased.cc
|
|
||||||
# absl::dynamic_annotations
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/base/dynamic_annotations.cc
|
|
||||||
# absl::malloc_internal
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/base/internal/low_level_alloc.cc
|
|
||||||
# absl::raw_logging_internal
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/base/internal/raw_logging.cc
|
|
||||||
# absl::spinlock_wait
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/base/internal/spinlock_wait.cc
|
|
||||||
# absl::throw_delegate
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/base/internal/throw_delegate.cc
|
|
||||||
# absl::strings
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/strings/ascii.cc \
|
|
||||||
external/abseil-cpp/absl/strings/charconv.cc \
|
|
||||||
external/abseil-cpp/absl/strings/escaping.cc \
|
|
||||||
external/abseil-cpp/absl/strings/internal/charconv_bigint.cc \
|
|
||||||
external/abseil-cpp/absl/strings/internal/charconv_parse.cc \
|
|
||||||
external/abseil-cpp/absl/strings/internal/memutil.cc \
|
|
||||||
external/abseil-cpp/absl/strings/match.cc \
|
|
||||||
external/abseil-cpp/absl/strings/numbers.cc \
|
|
||||||
external/abseil-cpp/absl/strings/str_cat.cc \
|
|
||||||
external/abseil-cpp/absl/strings/str_replace.cc \
|
|
||||||
external/abseil-cpp/absl/strings/str_split.cc \
|
|
||||||
external/abseil-cpp/absl/strings/string_view.cc \
|
|
||||||
external/abseil-cpp/absl/strings/substitute.cc
|
|
||||||
# absl::hashtablez_sampler
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/container/internal/hashtablez_sampler.cc \
|
|
||||||
external/abseil-cpp/absl/container/internal/hashtablez_sampler_force_weak_definition.cc
|
|
||||||
# absl::raw_hash_set
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/container/internal/raw_hash_set.cc
|
|
||||||
# absl::synchronization
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/synchronization/barrier.cc \
|
|
||||||
external/abseil-cpp/absl/synchronization/blocking_counter.cc \
|
|
||||||
external/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc \
|
|
||||||
external/abseil-cpp/absl/synchronization/internal/per_thread_sem.cc \
|
|
||||||
external/abseil-cpp/absl/synchronization/internal/waiter.cc \
|
|
||||||
external/abseil-cpp/absl/synchronization/notification.cc \
|
|
||||||
external/abseil-cpp/absl/synchronization/mutex.cc
|
|
||||||
# absl::graphcycles_internal
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/synchronization/internal/graphcycles.cc
|
|
||||||
# absl::time
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/time/civil_time.cc \
|
|
||||||
external/abseil-cpp/absl/time/clock.cc \
|
|
||||||
external/abseil-cpp/absl/time/duration.cc \
|
|
||||||
external/abseil-cpp/absl/time/format.cc \
|
|
||||||
external/abseil-cpp/absl/time/time.cc
|
|
||||||
# absl::time_zone
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc \
|
|
||||||
external/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc \
|
|
||||||
external/abseil-cpp/absl/time/internal/cctz/src/time_zone_if.cc \
|
|
||||||
external/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc \
|
|
||||||
external/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc \
|
|
||||||
external/abseil-cpp/absl/time/internal/cctz/src/time_zone_libc.cc \
|
|
||||||
external/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc \
|
|
||||||
external/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc \
|
|
||||||
external/abseil-cpp/absl/time/internal/cctz/src/zone_info_source.cc
|
|
||||||
# absl::stacktrace
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/debugging/stacktrace.cc
|
|
||||||
# absl::symbolize
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/debugging/symbolize.cc
|
|
||||||
# absl::demangle_internal
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/debugging/internal/demangle.cc
|
|
||||||
# absl::debugging_internal
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/debugging/internal/address_is_readable.cc \
|
|
||||||
external/abseil-cpp/absl/debugging/internal/elf_mem_image.cc \
|
|
||||||
external/abseil-cpp/absl/debugging/internal/vdso_support.cc
|
|
||||||
# absl::hash
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/hash/internal/hash.cc
|
|
||||||
# absl::city
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/hash/internal/city.cc
|
|
||||||
# absl::int128
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
external/abseil-cpp/absl/numeric/int128.cc
|
|
||||||
|
|
||||||
### Spline dependency
|
|
||||||
|
|
||||||
SFIZZ_C_FLAGS += -I$(SFIZZ_DIR)/src/external/spline
|
|
||||||
SFIZZ_SOURCES += src/external/spline/spline/spline.cpp
|
|
||||||
|
|
||||||
### Cpuid dependency
|
|
||||||
|
|
||||||
SFIZZ_C_FLAGS += \
|
|
||||||
-I$(SFIZZ_DIR)/src/external/cpuid/src \
|
|
||||||
-I$(SFIZZ_DIR)/src/external/cpuid/platform/src
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
src/external/cpuid/src/cpuid/cpuinfo.cpp \
|
|
||||||
src/external/cpuid/src/cpuid/version.cpp
|
|
||||||
|
|
||||||
### Pugixml dependency
|
|
||||||
|
|
||||||
SFIZZ_C_FLAGS += -I$(SFIZZ_DIR)/src/external/pugixml/src
|
|
||||||
SFIZZ_SOURCES += src/external/pugixml/src/pugixml.cpp
|
|
||||||
|
|
||||||
### Kissfft dependency
|
|
||||||
|
|
||||||
SFIZZ_C_FLAGS += \
|
|
||||||
-I$(SFIZZ_DIR)/src/external/kiss_fft \
|
|
||||||
-I$(SFIZZ_DIR)/src/external/kiss_fft/tools
|
|
||||||
SFIZZ_SOURCES += \
|
|
||||||
src/external/kiss_fft/kiss_fft.c \
|
|
||||||
src/external/kiss_fft/tools/kiss_fftr.c
|
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
SFIZZ_OBJECTS = $(SFIZZ_SOURCES:%=$(SFIZZ_BUILD_DIR)/%.o)
|
SFIZZ_OBJECTS = $(SFIZZ_SOURCES:%=$(SFIZZ_BUILD_DIR)/%.o)
|
||||||
|
|
|
||||||
88
editor/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
set(VSTGUI_BASEDIR "${CMAKE_CURRENT_SOURCE_DIR}/external/vstgui4")
|
||||||
|
include("cmake/Vstgui.cmake")
|
||||||
|
|
||||||
|
set(EDITOR_RESOURCES
|
||||||
|
logo.png
|
||||||
|
logo_text.png
|
||||||
|
logo_text_white.png
|
||||||
|
logo_text@2x.png
|
||||||
|
logo_text_white@2x.png
|
||||||
|
background.png
|
||||||
|
background@2x.png
|
||||||
|
icon_white.png
|
||||||
|
icon_white@2x.png
|
||||||
|
knob48.png
|
||||||
|
knob48@2x.png
|
||||||
|
Fonts/sfizz-fluentui-system-r20.ttf
|
||||||
|
Fonts/Roboto-Regular.ttf
|
||||||
|
PARENT_SCOPE)
|
||||||
|
|
||||||
|
function(copy_editor_resources SOURCE_DIR DESTINATION_DIR)
|
||||||
|
foreach(res ${EDITOR_RESOURCES})
|
||||||
|
get_filename_component(_dir "${res}" DIRECTORY)
|
||||||
|
file(MAKE_DIRECTORY "${DESTINATION_DIR}/${_dir}")
|
||||||
|
file(COPY "${SOURCE_DIR}/${res}" DESTINATION "${DESTINATION_DIR}/${_dir}")
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# editor
|
||||||
|
add_library(sfizz_editor STATIC EXCLUDE_FROM_ALL
|
||||||
|
src/editor/EditIds.h
|
||||||
|
src/editor/EditIds.cpp
|
||||||
|
src/editor/Editor.h
|
||||||
|
src/editor/Editor.cpp
|
||||||
|
src/editor/EditorController.h
|
||||||
|
src/editor/GUIComponents.h
|
||||||
|
src/editor/GUIComponents.cpp
|
||||||
|
src/editor/GUIPiano.h
|
||||||
|
src/editor/GUIPiano.cpp
|
||||||
|
src/editor/NativeHelpers.h
|
||||||
|
src/editor/NativeHelpers.cpp
|
||||||
|
src/editor/layout/main.hpp
|
||||||
|
src/editor/utility/vstgui_after.h
|
||||||
|
src/editor/utility/vstgui_before.h)
|
||||||
|
target_include_directories(sfizz_editor PUBLIC "src")
|
||||||
|
target_link_libraries(sfizz_editor PRIVATE sfizz-vstgui)
|
||||||
|
target_link_libraries(sfizz_editor PUBLIC absl::strings)
|
||||||
|
if(APPLE)
|
||||||
|
find_library(APPLE_APPKIT_LIBRARY "AppKit")
|
||||||
|
find_library(APPLE_CORESERVICES_LIBRARY "CoreServices")
|
||||||
|
find_library(APPLE_FOUNDATION_LIBRARY "Foundation")
|
||||||
|
target_sources(sfizz_editor PRIVATE
|
||||||
|
src/editor/NativeHelpers.mm)
|
||||||
|
target_link_libraries(sfizz_editor PRIVATE
|
||||||
|
"${APPLE_APPKIT_LIBRARY}"
|
||||||
|
"${APPLE_CORESERVICES_LIBRARY}"
|
||||||
|
"${APPLE_FOUNDATION_LIBRARY}")
|
||||||
|
target_compile_options(sfizz_editor PRIVATE "-fobjc-arc")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
if(WIN32)
|
||||||
|
#
|
||||||
|
elseif(APPLE)
|
||||||
|
#
|
||||||
|
else()
|
||||||
|
find_package(PkgConfig REQUIRED)
|
||||||
|
pkg_check_modules(sfizz-gio "gio-2.0" REQUIRED)
|
||||||
|
target_include_directories(sfizz_editor PRIVATE ${sfizz-gio_INCLUDE_DIRS})
|
||||||
|
target_link_libraries(sfizz_editor PRIVATE ${sfizz-gio_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
target_include_directories(sfizz_editor PRIVATE "../src/external") # ghc::filesystem
|
||||||
|
|
||||||
|
# layout tool
|
||||||
|
if(NOT CMAKE_CROSSCOMPILING)
|
||||||
|
add_executable(layout-maker
|
||||||
|
"tools/layout-maker/sources/layout.h"
|
||||||
|
"tools/layout-maker/sources/reader.cpp"
|
||||||
|
"tools/layout-maker/sources/reader.h"
|
||||||
|
"tools/layout-maker/sources/main.cpp")
|
||||||
|
target_link_libraries(layout-maker PRIVATE absl::strings)
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/editor/layout/main.hpp"
|
||||||
|
COMMAND "$<TARGET_FILE:layout-maker>"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/layout/main.fl"
|
||||||
|
> "${CMAKE_CURRENT_SOURCE_DIR}/src/editor/layout/main.hpp"
|
||||||
|
DEPENDS layout-maker "${CMAKE_CURRENT_SOURCE_DIR}/layout/main.fl")
|
||||||
|
endif()
|
||||||
224
editor/cmake/Vstgui.cmake
Normal file
|
|
@ -0,0 +1,224 @@
|
||||||
|
add_library(sfizz-vstgui STATIC EXCLUDE_FROM_ALL
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/animation/animations.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/animation/animator.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/animation/timingfunctions.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/cbitmap.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/cbitmapfilter.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/ccolor.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/cdatabrowser.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/cdrawcontext.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/cdrawmethods.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/cdropsource.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/cfileselector.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/cfont.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/cframe.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/cgradientview.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/cgraphicspath.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/clayeredviewcontainer.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/clinestyle.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/coffscreencontext.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/cautoanimation.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/cbuttons.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/ccolorchooser.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/ccontrol.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/cfontchooser.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/cknob.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/clistcontrol.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/cmoviebitmap.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/cmoviebutton.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/coptionmenu.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/cparamdisplay.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/cscrollbar.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/csearchtextedit.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/csegmentbutton.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/cslider.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/cspecialdigit.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/csplashscreen.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/cstringlist.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/cswitch.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/ctextedit.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/ctextlabel.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/cvumeter.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/controls/cxypad.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/copenglview.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/cpoint.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/crect.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/crowcolumnview.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/cscrollview.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/cshadowviewcontainer.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/csplitview.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/cstring.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/ctabview.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/ctooltipsupport.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/cview.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/cviewcontainer.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/cvstguitimer.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/genericstringlistdatabrowsersource.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/common/genericoptionmenu.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/platformfactory.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/vstguidebug.cpp")
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
target_sources(sfizz-vstgui PRIVATE
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/common/fileresourceinputstream.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/win32/direct2d/d2dbitmap.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/win32/direct2d/d2ddrawcontext.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/win32/direct2d/d2dfont.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/win32/direct2d/d2dgraphicspath.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/win32/win32datapackage.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/win32/win32dragging.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/win32/win32frame.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/win32/win32openglview.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/win32/win32optionmenu.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/win32/win32support.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/win32/win32resourcestream.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/win32/win32textedit.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/win32/win32factory.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/win32/winfileselector.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/win32/winstring.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/win32/wintimer.cpp")
|
||||||
|
elseif(APPLE)
|
||||||
|
target_sources(sfizz-vstgui PRIVATE
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/common/fileresourceinputstream.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/common/genericoptionmenu.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/common/generictextedit.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/carbon/hiviewframe.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/carbon/hiviewoptionmenu.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/carbon/hiviewtextedit.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/caviewlayer.mm"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/cfontmac.mm"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/cgbitmap.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/cgdrawcontext.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/cocoa/autoreleasepool.mm"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/cocoa/cocoahelpers.mm"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/cocoa/cocoaopenglview.mm"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/cocoa/cocoatextedit.mm"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/cocoa/nsviewdraggingsession.mm"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/cocoa/nsviewframe.mm"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/cocoa/nsviewoptionmenu.mm"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/macclipboard.mm"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/macfactory.mm"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/macfileselector.mm"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/macglobals.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/macstring.mm"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/mactimer.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/mac/quartzgraphicspath.cpp")
|
||||||
|
else()
|
||||||
|
target_sources(sfizz-vstgui PRIVATE
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/common/fileresourceinputstream.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/common/generictextedit.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/linux/cairobitmap.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/linux/cairocontext.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/linux/cairofont.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/linux/cairogradient.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/linux/cairopath.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/linux/linuxfactory.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/linux/linuxstring.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/linux/x11dragging.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/linux/x11fileselector.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/linux/x11frame.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/linux/x11platform.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/linux/x11timer.cpp"
|
||||||
|
"${VSTGUI_BASEDIR}/vstgui/lib/platform/linux/x11utils.cpp")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_include_directories(sfizz-vstgui PUBLIC "${VSTGUI_BASEDIR}")
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
if (NOT MSVC)
|
||||||
|
# autolinked on MSVC with pragmas
|
||||||
|
target_link_libraries(sfizz-vstgui PRIVATE
|
||||||
|
"opengl32"
|
||||||
|
"d2d1"
|
||||||
|
"dwrite"
|
||||||
|
"dwmapi"
|
||||||
|
"windowscodecs"
|
||||||
|
"shlwapi")
|
||||||
|
endif()
|
||||||
|
elseif(APPLE)
|
||||||
|
target_link_libraries(sfizz-vstgui PRIVATE
|
||||||
|
"${APPLE_COREFOUNDATION_LIBRARY}"
|
||||||
|
"${APPLE_FOUNDATION_LIBRARY}"
|
||||||
|
"${APPLE_COCOA_LIBRARY}"
|
||||||
|
"${APPLE_OPENGL_LIBRARY}"
|
||||||
|
"${APPLE_ACCELERATE_LIBRARY}"
|
||||||
|
"${APPLE_QUARTZCORE_LIBRARY}"
|
||||||
|
"${APPLE_CARBON_LIBRARY}"
|
||||||
|
"${APPLE_AUDIOTOOLBOX_LIBRARY}"
|
||||||
|
"${APPLE_COREAUDIO_LIBRARY}"
|
||||||
|
"${APPLE_COREMIDI_LIBRARY}")
|
||||||
|
else()
|
||||||
|
find_package(X11 REQUIRED)
|
||||||
|
find_package(Freetype REQUIRED)
|
||||||
|
find_package(PkgConfig REQUIRED)
|
||||||
|
pkg_check_modules(LIBXCB REQUIRED xcb)
|
||||||
|
pkg_check_modules(LIBXCB_UTIL REQUIRED xcb-util)
|
||||||
|
pkg_check_modules(LIBXCB_CURSOR REQUIRED xcb-cursor)
|
||||||
|
pkg_check_modules(LIBXCB_KEYSYMS REQUIRED xcb-keysyms)
|
||||||
|
pkg_check_modules(LIBXCB_XKB REQUIRED xcb-xkb)
|
||||||
|
pkg_check_modules(LIBXKB_COMMON REQUIRED xkbcommon)
|
||||||
|
pkg_check_modules(LIBXKB_COMMON_X11 REQUIRED xkbcommon-x11)
|
||||||
|
pkg_check_modules(CAIRO REQUIRED cairo)
|
||||||
|
pkg_check_modules(FONTCONFIG REQUIRED fontconfig)
|
||||||
|
pkg_check_modules(GLIB REQUIRED glib-2.0)
|
||||||
|
target_include_directories(sfizz-vstgui PRIVATE
|
||||||
|
${X11_INCLUDE_DIRS}
|
||||||
|
${FREETYPE_INCLUDE_DIRS}
|
||||||
|
${LIBXCB_INCLUDE_DIRS}
|
||||||
|
${LIBXCB_UTIL_INCLUDE_DIRS}
|
||||||
|
${LIBXCB_CURSOR_INCLUDE_DIRS}
|
||||||
|
${LIBXCB_KEYSYMS_INCLUDE_DIRS}
|
||||||
|
${LIBXCB_XKB_INCLUDE_DIRS}
|
||||||
|
${LIBXKB_COMMON_INCLUDE_DIRS}
|
||||||
|
${LIBXKB_COMMON_X11_INCLUDE_DIRS}
|
||||||
|
${CAIRO_INCLUDE_DIRS}
|
||||||
|
${FONTCONFIG_INCLUDE_DIRS}
|
||||||
|
${GLIB_INCLUDE_DIRS})
|
||||||
|
target_link_libraries(sfizz-vstgui PRIVATE
|
||||||
|
${X11_LIBRARIES}
|
||||||
|
${FREETYPE_LIBRARIES}
|
||||||
|
${LIBXCB_LIBRARIES}
|
||||||
|
${LIBXCB_UTIL_LIBRARIES}
|
||||||
|
${LIBXCB_CURSOR_LIBRARIES}
|
||||||
|
${LIBXCB_KEYSYMS_LIBRARIES}
|
||||||
|
${LIBXCB_XKB_LIBRARIES}
|
||||||
|
${LIBXKB_COMMON_LIBRARIES}
|
||||||
|
${LIBXKB_COMMON_X11_LIBRARIES}
|
||||||
|
${CAIRO_LIBRARIES}
|
||||||
|
${FONTCONFIG_LIBRARIES}
|
||||||
|
${GLIB_LIBRARIES})
|
||||||
|
find_library(DL_LIBRARY "dl")
|
||||||
|
if(DL_LIBRARY)
|
||||||
|
target_link_libraries(sfizz-vstgui PRIVATE "${DL_LIBRARY}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(${CMAKE_BUILD_TYPE} MATCHES "Debug")
|
||||||
|
target_compile_definitions(sfizz-vstgui PRIVATE "DEVELOPMENT")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(${CMAKE_BUILD_TYPE} MATCHES "Release")
|
||||||
|
target_compile_definitions(sfizz-vstgui PRIVATE "RELEASE")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||||
|
# higher C++ requirement on Windows
|
||||||
|
set_property(TARGET sfizz-vstgui PROPERTY CXX_STANDARD 14)
|
||||||
|
# Windows 10 RS2 DDI for custom fonts
|
||||||
|
target_compile_definitions(sfizz-vstgui PRIVATE "NTDDI_VERSION=0x0A000003")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||||
|
target_compile_options(sfizz-vstgui PRIVATE
|
||||||
|
"-Wno-deprecated-copy"
|
||||||
|
"-Wno-deprecated-declarations"
|
||||||
|
"-Wno-extra"
|
||||||
|
"-Wno-ignored-qualifiers"
|
||||||
|
"-Wno-multichar"
|
||||||
|
"-Wno-reorder"
|
||||||
|
"-Wno-sign-compare"
|
||||||
|
"-Wno-unknown-pragmas"
|
||||||
|
"-Wno-unused-function"
|
||||||
|
"-Wno-unused-parameter"
|
||||||
|
"-Wno-unused-variable")
|
||||||
|
endif()
|
||||||
1
editor/external/vstgui4
vendored
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 055cbcc9ae858f0b07d5d86c205a1111e2fba7a4
|
||||||
312
editor/layout/main.fl
Normal file
|
|
@ -0,0 +1,312 @@
|
||||||
|
# data file for the Fltk User Interface Designer (fluid)
|
||||||
|
version 1.0305
|
||||||
|
header_name {.h}
|
||||||
|
code_name {.cxx}
|
||||||
|
widget_class mainView {open
|
||||||
|
xywh {576 416 800 475} type Double
|
||||||
|
class LogicalGroup visible
|
||||||
|
} {
|
||||||
|
Fl_Box {} {
|
||||||
|
image {../resources/background.png} xywh {190 110 600 280}
|
||||||
|
class Background
|
||||||
|
}
|
||||||
|
Fl_Group {} {
|
||||||
|
comment {theme=darkTheme} open
|
||||||
|
xywh {0 0 800 110}
|
||||||
|
class LogicalGroup
|
||||||
|
} {
|
||||||
|
Fl_Group {} {open
|
||||||
|
xywh {5 4 175 101} box ROUNDED_BOX align 0
|
||||||
|
class RoundedGroup
|
||||||
|
} {
|
||||||
|
Fl_Box {} {
|
||||||
|
comment {tag=kTagFirstChangePanel+kPanelGeneral}
|
||||||
|
image {../resources/logo_text_white.png} xywh {35 9 120 60}
|
||||||
|
class SfizzMainButton
|
||||||
|
}
|
||||||
|
Fl_Button {} {
|
||||||
|
comment {tag=kTagFirstChangePanel+kPanelGeneral}
|
||||||
|
xywh {49 73 25 25} labelsize 24
|
||||||
|
class HomeButton
|
||||||
|
}
|
||||||
|
Fl_Button {} {
|
||||||
|
comment {tag=kTagFirstChangePanel+kPanelControls}
|
||||||
|
xywh {81 73 25 25} labelsize 24
|
||||||
|
class CCButton
|
||||||
|
}
|
||||||
|
Fl_Button {} {
|
||||||
|
comment {tag=kTagFirstChangePanel+kPanelSettings}
|
||||||
|
xywh {112 73 25 25} labelsize 24
|
||||||
|
class SettingsButton
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fl_Group {} {open
|
||||||
|
xywh {185 5 380 100} box ROUNDED_BOX
|
||||||
|
class RoundedGroup
|
||||||
|
} {
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Separator 1}
|
||||||
|
xywh {195 41 360 5} box BORDER_BOX labeltype NO_LABEL
|
||||||
|
class HLine
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Separator 2}
|
||||||
|
xywh {195 73 360 5} box BORDER_BOX labeltype NO_LABEL
|
||||||
|
class HLine
|
||||||
|
}
|
||||||
|
Fl_Box sfzFileLabel_ {
|
||||||
|
label {DefaultInstrument.sfz}
|
||||||
|
comment {tag=kTagLoadSfzFile}
|
||||||
|
xywh {195 11 250 31} labelsize 20 align 20
|
||||||
|
class ClickableLabel
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Key switch:}
|
||||||
|
xywh {195 44 250 30} labelsize 20 align 20
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Voices:}
|
||||||
|
xywh {195 76 60 25} labelsize 12 align 24
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Button {} {
|
||||||
|
comment {tag=kTagPreviousSfzFile}
|
||||||
|
xywh {480 14 25 25} labelsize 24
|
||||||
|
class PreviousFileButton
|
||||||
|
}
|
||||||
|
Fl_Button {} {
|
||||||
|
comment {tag=kTagNextSfzFile}
|
||||||
|
xywh {505 14 25 25} labelsize 24
|
||||||
|
class NextFileButton
|
||||||
|
}
|
||||||
|
Fl_Button fileOperationsMenu_ {
|
||||||
|
comment {tag=kTagFileOperations}
|
||||||
|
xywh {530 14 25 25} labelsize 24
|
||||||
|
class ChevronDropDown
|
||||||
|
}
|
||||||
|
Fl_Box infoVoicesLabel_ {
|
||||||
|
xywh {260 76 50 25} labelsize 12 align 16
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Max:}
|
||||||
|
xywh {315 76 60 25} labelsize 12 align 24
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box numVoicesLabel_ {
|
||||||
|
xywh {380 76 50 25} labelsize 12 align 16
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Memory:}
|
||||||
|
xywh {435 76 60 25} labelsize 12 align 24
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box memoryLabel_ {
|
||||||
|
xywh {500 76 50 25} labelsize 12 align 16
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fl_Group {} {open
|
||||||
|
xywh {570 5 225 100} box ROUNDED_BOX
|
||||||
|
class RoundedGroup
|
||||||
|
} {
|
||||||
|
Fl_Dial {} {
|
||||||
|
xywh {615 20 48 48} value 0.5 hide
|
||||||
|
class Knob48
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label Center
|
||||||
|
xywh {610 70 60 5} labelsize 12 hide
|
||||||
|
class ValueLabel
|
||||||
|
}
|
||||||
|
Fl_Dial volumeSlider_ {
|
||||||
|
comment {tag=kTagSetVolume}
|
||||||
|
xywh {680 20 48 48} value 0.5
|
||||||
|
class StyledKnob
|
||||||
|
}
|
||||||
|
Fl_Box volumeLabel_ {
|
||||||
|
label {0.0 dB}
|
||||||
|
xywh {675 70 60 22} labelsize 12
|
||||||
|
class ValueLabel
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
xywh {745 20 35 55} box BORDER_BOX
|
||||||
|
class VMeter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fl_Group {subPanels_[kPanelGeneral]} {
|
||||||
|
xywh {5 110 791 285}
|
||||||
|
class LogicalGroup
|
||||||
|
} {
|
||||||
|
Fl_Group {} {open
|
||||||
|
xywh {5 110 175 280} box ROUNDED_BOX
|
||||||
|
class RoundedGroup
|
||||||
|
} {
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Curves:}
|
||||||
|
xywh {20 120 60 25} align 20
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Masters:}
|
||||||
|
xywh {20 145 60 25} align 20
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Groups:}
|
||||||
|
xywh {20 170 60 25} align 20
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Regions:}
|
||||||
|
xywh {20 195 60 25} align 20
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Samples:}
|
||||||
|
xywh {20 220 60 25} align 20
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box infoCurvesLabel_ {
|
||||||
|
label 0
|
||||||
|
xywh {120 120 40 25} align 16
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box infoMastersLabel_ {
|
||||||
|
label 0
|
||||||
|
xywh {120 145 40 25} align 16
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box infoGroupsLabel_ {
|
||||||
|
label 0
|
||||||
|
xywh {120 170 40 25} align 16
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box infoRegionsLabel_ {
|
||||||
|
label 0
|
||||||
|
xywh {120 195 40 25} align 16
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
Fl_Box infoSamplesLabel_ {
|
||||||
|
label 0
|
||||||
|
xywh {120 220 40 25} align 16
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fl_Group {subPanels_[kPanelControls]} {
|
||||||
|
xywh {5 110 790 285} hide
|
||||||
|
class LogicalGroup
|
||||||
|
} {
|
||||||
|
Fl_Group {} {open
|
||||||
|
xywh {5 110 790 285} box ROUNDED_BOX
|
||||||
|
class RoundedGroup
|
||||||
|
} {
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Controls not available}
|
||||||
|
xywh {5 110 790 285} labelsize 40
|
||||||
|
class Label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fl_Group {subPanels_[kPanelSettings]} {open
|
||||||
|
xywh {5 109 790 286} hide
|
||||||
|
class LogicalGroup
|
||||||
|
} {
|
||||||
|
Fl_Group {} {
|
||||||
|
label Engine open
|
||||||
|
xywh {260 135 280 100} box ROUNDED_BOX labelsize 12 align 17
|
||||||
|
class TitleGroup
|
||||||
|
} {
|
||||||
|
Fl_Spinner numVoicesSlider_ {
|
||||||
|
comment {tag=kTagSetNumVoices}
|
||||||
|
xywh {285 195 60 25} labelsize 12 textsize 12
|
||||||
|
class ValueMenu
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label Polyphony
|
||||||
|
xywh {275 155 80 25} labelsize 12
|
||||||
|
class ValueLabel
|
||||||
|
}
|
||||||
|
Fl_Spinner oversamplingSlider_ {
|
||||||
|
comment {tag=kTagSetOversampling}
|
||||||
|
xywh {370 195 60 25} labelsize 12 textsize 12
|
||||||
|
class ValueMenu
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label Oversampling
|
||||||
|
xywh {360 155 80 25} labelsize 12
|
||||||
|
class ValueLabel
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Preload size}
|
||||||
|
xywh {445 155 80 25} labelsize 12
|
||||||
|
class ValueLabel
|
||||||
|
}
|
||||||
|
Fl_Spinner preloadSizeSlider_ {
|
||||||
|
comment {tag=kTagSetPreloadSize}
|
||||||
|
xywh {455 195 60 25} labelsize 12 textsize 12
|
||||||
|
class ValueMenu
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fl_Group {} {
|
||||||
|
label Tuning open
|
||||||
|
xywh {205 270 390 100} box ROUNDED_BOX labelsize 12 align 17
|
||||||
|
class TitleGroup
|
||||||
|
} {
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Root key}
|
||||||
|
xywh {330 290 80 25} labelsize 12
|
||||||
|
class ValueLabel
|
||||||
|
}
|
||||||
|
Fl_Spinner tuningFrequencySlider_ {
|
||||||
|
comment {tag=kTagSetTuningFrequency}
|
||||||
|
xywh {425 330 60 25} labelsize 12 textsize 12
|
||||||
|
class ValueMenu
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label Frequency
|
||||||
|
xywh {415 290 80 25} labelsize 12
|
||||||
|
class ValueLabel
|
||||||
|
}
|
||||||
|
Fl_Dial stretchedTuningSlider_ {
|
||||||
|
comment {tag=kTagSetStretchedTuning}
|
||||||
|
xywh {515 315 48 48} value 0.5
|
||||||
|
class StyledKnob
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label Stretch
|
||||||
|
xywh {500 290 80 25} labelsize 12
|
||||||
|
class ValueLabel
|
||||||
|
}
|
||||||
|
Fl_Box {} {
|
||||||
|
label {Scala file}
|
||||||
|
xywh {225 290 100 25} labelsize 12
|
||||||
|
class ValueLabel
|
||||||
|
}
|
||||||
|
Fl_Button scalaFileButton_ {
|
||||||
|
label DefaultScale
|
||||||
|
comment {tag=kTagLoadScalaFile}
|
||||||
|
xywh {225 330 100 25} labelsize 12
|
||||||
|
class ValueButton
|
||||||
|
}
|
||||||
|
Fl_Spinner scalaRootKeySlider_ {
|
||||||
|
comment {tag=kTagSetScalaRootKey}
|
||||||
|
xywh {340 330 35 25} labelsize 12 textsize 12
|
||||||
|
class ValueMenu
|
||||||
|
}
|
||||||
|
Fl_Spinner scalaRootOctaveSlider_ {
|
||||||
|
comment {tag=kTagSetScalaRootKey}
|
||||||
|
xywh {375 330 30 25} labelsize 12 textsize 12
|
||||||
|
class ValueMenu
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Fl_Box piano_ {selected
|
||||||
|
xywh {5 400 790 70} labelsize 12
|
||||||
|
class Piano
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
editor/resources/Fonts/Roboto-Regular.ttf
Normal file
BIN
editor/resources/Fonts/sfizz-fluentui-system-r20.ttf
Normal file
BIN
editor/resources/background.png
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
editor/resources/background@2x.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
editor/resources/icon_white.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
253
editor/resources/icon_white.svg
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
editor/resources/icon_white@2x.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
editor/resources/knob.knob
Normal file
BIN
editor/resources/knob48.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
editor/resources/knob48@2x.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
BIN
editor/resources/logo_text.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
252
editor/resources/logo_text.svg
Normal file
|
|
@ -0,0 +1,252 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
inkscape:export-ydpi="192"
|
||||||
|
inkscape:export-xdpi="192"
|
||||||
|
inkscape:export-filename="/home/jpc/documents/projects/sfizz/editor/resources/logo_text@2x.png"
|
||||||
|
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
|
||||||
|
sodipodi:docname="logo_text.svg"
|
||||||
|
id="svg8"
|
||||||
|
version="1.1"
|
||||||
|
viewBox="0 0 105.83333 66.145836"
|
||||||
|
height="250"
|
||||||
|
width="400">
|
||||||
|
<title
|
||||||
|
id="title1469">sfizz logo</title>
|
||||||
|
<defs
|
||||||
|
id="defs2">
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient1445"
|
||||||
|
inkscape:collect="always">
|
||||||
|
<stop
|
||||||
|
id="stop1441"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#646464;stop-opacity:1" />
|
||||||
|
<stop
|
||||||
|
id="stop1443"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#000000;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="fillet_chamfer"
|
||||||
|
id="path-effect1150"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1"
|
||||||
|
satellites_param="F,0,0,1,0,1,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,1,0,2 @ F,0,0,1,0,0,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.47797039,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.51256137,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.33778335,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.27944107,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.25554572,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.29009315,0,2"
|
||||||
|
unit="mm"
|
||||||
|
method="auto"
|
||||||
|
mode="C"
|
||||||
|
radius="1"
|
||||||
|
chamfer_steps="2"
|
||||||
|
flexible="false"
|
||||||
|
use_knot_distance="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
apply_with_radius="true"
|
||||||
|
only_selected="false"
|
||||||
|
hide_knots="false" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
hide_knots="false"
|
||||||
|
only_selected="false"
|
||||||
|
apply_with_radius="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
use_knot_distance="true"
|
||||||
|
flexible="false"
|
||||||
|
chamfer_steps="2"
|
||||||
|
radius="1"
|
||||||
|
mode="C"
|
||||||
|
method="auto"
|
||||||
|
unit="mm"
|
||||||
|
satellites_param="F,0,0,1,0,1,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,1,0,2 @ F,0,0,1,0,0,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.47797039,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.51256137,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.33778335,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.27944107,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.25554572,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.29009315,0,2"
|
||||||
|
lpeversion="1"
|
||||||
|
is_visible="true"
|
||||||
|
id="path-effect1136"
|
||||||
|
effect="fillet_chamfer" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
hide_knots="false"
|
||||||
|
only_selected="false"
|
||||||
|
apply_with_radius="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
use_knot_distance="true"
|
||||||
|
flexible="false"
|
||||||
|
chamfer_steps="2"
|
||||||
|
radius="1"
|
||||||
|
mode="C"
|
||||||
|
method="auto"
|
||||||
|
unit="mm"
|
||||||
|
satellites_param="F,0,0,1,0,1,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,1,0,2 @ F,0,0,1,0,0,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.47797039,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.51256137,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.33778335,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.27944107,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.25554572,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.29009315,0,2"
|
||||||
|
lpeversion="1"
|
||||||
|
is_visible="true"
|
||||||
|
id="path-effect968"
|
||||||
|
effect="fillet_chamfer" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="fillet_chamfer"
|
||||||
|
id="path-effect921"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1"
|
||||||
|
satellites_param="F,0,0,1,0,1,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,1,0,2 @ F,0,0,1,0,0,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.47797039,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.51256137,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.33778335,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.27944107,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.25554572,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.29009315,0,2"
|
||||||
|
unit="mm"
|
||||||
|
method="auto"
|
||||||
|
mode="C"
|
||||||
|
radius="1"
|
||||||
|
chamfer_steps="2"
|
||||||
|
flexible="false"
|
||||||
|
use_knot_distance="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
apply_with_radius="true"
|
||||||
|
only_selected="false"
|
||||||
|
hide_knots="false" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
hide_knots="false"
|
||||||
|
only_selected="false"
|
||||||
|
apply_with_radius="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
use_knot_distance="true"
|
||||||
|
flexible="false"
|
||||||
|
chamfer_steps="2"
|
||||||
|
radius="1"
|
||||||
|
mode="C"
|
||||||
|
method="auto"
|
||||||
|
unit="mm"
|
||||||
|
satellites_param="F,0,0,1,0,1,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,1,0,2 @ F,0,0,1,0,0,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.47797039,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.51256137,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.33778335,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.27944107,0,2 | F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.25554572,0,2 @ F,0,0,1,0,0,0,2 @ F,0,0,1,0,0.29009315,0,2"
|
||||||
|
lpeversion="1"
|
||||||
|
is_visible="true"
|
||||||
|
id="path-effect1183"
|
||||||
|
effect="fillet_chamfer" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
end_linecap_type="zerowidth"
|
||||||
|
scale_width="1"
|
||||||
|
miter_limit="4"
|
||||||
|
linejoin_type="round"
|
||||||
|
start_linecap_type="zerowidth"
|
||||||
|
interpolator_beta="0.2"
|
||||||
|
interpolator_type="CubicBezierFit"
|
||||||
|
sort_points="true"
|
||||||
|
offset_points="0.19099662,0.36320029 | 0.41721681,0.40988822 | 0.9095762,0.070646707"
|
||||||
|
lpeversion="1"
|
||||||
|
is_visible="true"
|
||||||
|
id="path-effect1172"
|
||||||
|
effect="powerstroke" />
|
||||||
|
<clipPath
|
||||||
|
id="clipPath917"
|
||||||
|
clipPathUnits="userSpaceOnUse">
|
||||||
|
<rect
|
||||||
|
y="68.872978"
|
||||||
|
x="24.792475"
|
||||||
|
height="25.252825"
|
||||||
|
width="39.659527"
|
||||||
|
id="rect919"
|
||||||
|
style="fill:#ffffff;stroke:none;stroke-width:2;stroke-linecap:round;paint-order:markers stroke fill" />
|
||||||
|
</clipPath>
|
||||||
|
<linearGradient
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
y2="231.60674"
|
||||||
|
x2="539.22601"
|
||||||
|
y1="190.42654"
|
||||||
|
x1="539.22601"
|
||||||
|
id="linearGradient1447"
|
||||||
|
xlink:href="#linearGradient1445"
|
||||||
|
inkscape:collect="always"
|
||||||
|
gradientTransform="translate(34.589224,10.333824)" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
fit-margin-bottom="10"
|
||||||
|
fit-margin-right="10"
|
||||||
|
fit-margin-left="10"
|
||||||
|
fit-margin-top="10"
|
||||||
|
inkscape:snap-bbox-midpoints="true"
|
||||||
|
inkscape:snap-center="true"
|
||||||
|
inkscape:snap-bbox-edge-midpoints="true"
|
||||||
|
inkscape:bbox-paths="true"
|
||||||
|
inkscape:snap-bbox="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:window-y="27"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-height="1008"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
showguides="false"
|
||||||
|
inkscape:snap-global="false"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:document-rotation="0"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:cy="53.822531"
|
||||||
|
inkscape:cx="17.632385"
|
||||||
|
inkscape:zoom="1"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
borderopacity="1.0"
|
||||||
|
bordercolor="#666666"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
id="base"
|
||||||
|
units="px">
|
||||||
|
<sodipodi:guide
|
||||||
|
id="guide899"
|
||||||
|
orientation="1,0"
|
||||||
|
position="-452.4563,176.31198" />
|
||||||
|
<sodipodi:guide
|
||||||
|
id="guide901"
|
||||||
|
orientation="0,-1"
|
||||||
|
position="-351.71366,154.32488" />
|
||||||
|
<sodipodi:guide
|
||||||
|
id="guide1008"
|
||||||
|
orientation="1,0"
|
||||||
|
position="-536.98274,156.82863" />
|
||||||
|
<sodipodi:guide
|
||||||
|
id="guide1185"
|
||||||
|
orientation="1,0"
|
||||||
|
position="-351.75629,154.33106" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title>sfizz logo</dc:title>
|
||||||
|
<dc:date>2020-05-16</dc:date>
|
||||||
|
<dc:creator>
|
||||||
|
<cc:Agent>
|
||||||
|
<dc:title>Tobiasz 'unfa' Karoń</dc:title>
|
||||||
|
</cc:Agent>
|
||||||
|
</dc:creator>
|
||||||
|
<dc:rights>
|
||||||
|
<cc:Agent>
|
||||||
|
<dc:title>CC-0</dc:title>
|
||||||
|
</cc:Agent>
|
||||||
|
</dc:rights>
|
||||||
|
<cc:license
|
||||||
|
rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
|
||||||
|
</cc:Work>
|
||||||
|
<cc:License
|
||||||
|
rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
|
||||||
|
</cc:License>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
transform="translate(-495.92008,-191.91875)"
|
||||||
|
id="layer1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
inkscape:label="Layer 1">
|
||||||
|
<path
|
||||||
|
id="path1439"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:34.8154px;line-height:1.25;font-family:ABeeZee;-inkscape-font-specification:ABeeZee;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient1447);fill-opacity:1;stroke:none;stroke-width:0.264584"
|
||||||
|
d="m 569.95053,215.93967 h 13.61282 v 2.40226 l -9.9572,12.91651 h 10.13128 v 2.78523 h -13.99579 v -2.47189 l 9.99202,-12.91651 h -9.78313 z m -16.4328,0 h 13.61282 v 2.40226 l -9.9572,12.91651 h 10.13128 v 2.78523 h -13.99579 v -2.47189 l 9.99202,-12.91651 h -9.78313 z m -6.38378,18.104 h -3.13338 l 3.1682,-18.104 h 3.13339 z m 2.33264,-21.20257 c -0.64989,0 -1.14891,-0.18568 -1.49707,-0.55705 -0.32494,-0.39457 -0.48741,-0.84717 -0.48741,-1.3578 0,-0.74273 0.2321,-1.33459 0.69631,-1.77559 0.4642,-0.46421 1.04446,-0.69631 1.74077,-0.69631 0.64989,0 1.1373,0.19729 1.46224,0.59187 0.34815,0.37136 0.52223,0.81235 0.52223,1.32298 0,0.74273 -0.2321,1.34619 -0.6963,1.8104 -0.46421,0.441 -1.04446,0.6615 -1.74077,0.6615 z m -12.24537,3.76006 h 5.36157 l -0.48741,2.7156 h -5.36157 l -3.06376,17.23362 c -0.18568,1.02125 -0.4526,1.88003 -0.80075,2.57634 -0.34815,0.71952 -0.76594,1.29978 -1.25336,1.74077 -0.48741,0.44099 -1.04446,0.75433 -1.67114,0.94002 -0.62667,0.20889 -1.29977,0.31334 -2.01929,0.31334 -0.76594,0 -1.46225,-0.10445 -2.08892,-0.31334 -0.64989,-0.20889 -1.21854,-0.49902 -1.70596,-0.87039 l 1.25336,-2.57634 c 0.32494,0.32495 0.70791,0.58026 1.1489,0.76594 0.41779,0.18568 0.8936,0.27852 1.42744,0.27852 0.62667,0 1.16051,-0.2205 1.6015,-0.66149 0.46421,-0.44099 0.78915,-1.14891 0.97484,-2.12374 l 3.06375,-17.30325 h -2.78523 l 0.48741,-2.7156 h 2.78524 l 0.52223,-2.78523 c 0.39457,-2.13535 1.14891,-3.65562 2.263,-4.56082 1.11409,-0.92841 2.54152,-1.39262 4.28229,-1.39262 0.95162,0 1.83361,0.12766 2.64597,0.38297 0.81236,0.23211 1.54348,0.52224 2.19337,0.87039 l -1.21854,2.64597 c -0.53383,-0.27853 -1.09088,-0.53384 -1.67114,-0.76594 -0.55704,-0.23211 -1.21853,-0.34816 -1.98447,-0.34816 -0.85878,0 -1.5899,0.25531 -2.19337,0.76594 -0.60347,0.48742 -0.99804,1.25336 -1.18373,2.29782 z m -21.96217,13.36911 c 0.60347,0.53384 1.3578,0.96323 2.263,1.28817 0.92841,0.32495 1.91485,0.48742 2.95931,0.48742 1.29977,0 2.2746,-0.20889 2.92449,-0.62668 0.6731,-0.44099 1.00965,-0.99804 1.00965,-1.67114 0,-0.34815 -0.0696,-0.6731 -0.20889,-0.97483 -0.11605,-0.30173 -0.34816,-0.59186 -0.69631,-0.87039 -0.32495,-0.27852 -0.77755,-0.54544 -1.3578,-0.80075 -0.58026,-0.27852 -1.33459,-0.58025 -2.263,-0.9052 -1.71756,-0.58026 -2.99413,-1.26496 -3.8297,-2.05411 -0.83557,-0.81236 -1.25335,-1.92645 -1.25335,-3.34228 0,-0.69631 0.15087,-1.34619 0.4526,-1.94966 0.32495,-0.60347 0.77755,-1.1257 1.3578,-1.56669 0.60347,-0.46421 1.32299,-0.82397 2.15856,-1.07928 0.85878,-0.25531 1.83361,-0.38297 2.92449,-0.38297 1.18372,0 2.21658,0.12766 3.09857,0.38297 0.9052,0.2321 1.71756,0.53383 2.43708,0.9052 l -0.87039,2.57634 c -0.62667,-0.37137 -1.34619,-0.6731 -2.15855,-0.9052 -0.78915,-0.2321 -1.67114,-0.34815 -2.64597,-0.34815 -1.20693,0 -2.12374,0.24371 -2.75042,0.73112 -0.62668,0.48741 -0.94002,1.02125 -0.94002,1.60151 0,0.27852 0.0464,0.53383 0.13927,0.76594 0.11605,0.2321 0.31333,0.4526 0.59186,0.66149 0.27852,0.20889 0.64988,0.41779 1.11409,0.62668 0.46421,0.20889 1.04446,0.42938 1.74077,0.66149 1.13731,0.39457 2.10053,0.80075 2.88968,1.21854 0.78915,0.39457 1.42743,0.83557 1.91485,1.32298 0.48741,0.48742 0.83557,1.02126 1.04446,1.60151 0.20889,0.55705 0.31334,1.18372 0.31334,1.88003 0,0.81236 -0.17408,1.54348 -0.52223,2.19337 -0.34816,0.64989 -0.83558,1.20693 -1.46225,1.67114 -0.62668,0.44099 -1.39262,0.77754 -2.29782,1.00965 -0.88199,0.25531 -1.86842,0.38297 -2.95931,0.38297 -1.39261,0 -2.63436,-0.17408 -3.72524,-0.52223 -1.09089,-0.34815 -1.99609,-0.80075 -2.71561,-1.3578 z"
|
||||||
|
sodipodi:nodetypes="cccccccccccccccccccccccccccscscscscsccccccscsccccsccccccccsccccscccccscscccccscccsccccssscssccccssccsscc" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 12 KiB |
BIN
editor/resources/logo_text@2x.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
editor/resources/logo_text_white.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
editor/resources/logo_text_white@2x.png
Normal file
|
After Width: | Height: | Size: 4 KiB |
32
editor/src/editor/EditIds.cpp
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#include "EditIds.h"
|
||||||
|
|
||||||
|
EditRange EditRange::get(EditId id)
|
||||||
|
{
|
||||||
|
switch (id) {
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
return {};
|
||||||
|
case EditId::Volume:
|
||||||
|
return { 0, -60, 6 };
|
||||||
|
case EditId::Polyphony:
|
||||||
|
return { 64, 1, 256 };
|
||||||
|
case EditId::Oversampling:
|
||||||
|
return { 0, 0, 3 };
|
||||||
|
case EditId::PreloadSize:
|
||||||
|
return { 8192, 1024, 65536 };
|
||||||
|
case EditId::ScalaRootKey:
|
||||||
|
return { 60, 0, 127 };
|
||||||
|
case EditId::TuningFrequency:
|
||||||
|
return { 440, 300, 500 };
|
||||||
|
case EditId::StretchTuning:
|
||||||
|
return { 0, 0, 1 };
|
||||||
|
case EditId::UIActivePanel:
|
||||||
|
return { 0, 0, 255 };
|
||||||
|
}
|
||||||
|
}
|
||||||
37
editor/src/editor/EditIds.h
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
enum class EditId : int {
|
||||||
|
SfzFile,
|
||||||
|
Volume,
|
||||||
|
Polyphony,
|
||||||
|
Oversampling,
|
||||||
|
PreloadSize,
|
||||||
|
ScalaFile,
|
||||||
|
ScalaRootKey,
|
||||||
|
TuningFrequency,
|
||||||
|
StretchTuning,
|
||||||
|
UINumCurves,
|
||||||
|
UINumMasters,
|
||||||
|
UINumGroups,
|
||||||
|
UINumRegions,
|
||||||
|
UINumPreloadedSamples,
|
||||||
|
UINumActiveVoices,
|
||||||
|
UIActivePanel,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EditRange {
|
||||||
|
float def = 0.0;
|
||||||
|
float min = 0.0;
|
||||||
|
float max = 1.0;
|
||||||
|
constexpr EditRange() = default;
|
||||||
|
constexpr EditRange(float def, float min, float max)
|
||||||
|
: def(def), min(min), max(max) {}
|
||||||
|
static EditRange get(EditId id);
|
||||||
|
};
|
||||||
67
editor/src/editor/EditValue.h
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <new>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
class EditValue {
|
||||||
|
public:
|
||||||
|
constexpr EditValue() : tag(Nil) {}
|
||||||
|
EditValue(float value) { reset(value); }
|
||||||
|
EditValue(std::string value) { reset(value); }
|
||||||
|
~EditValue() { reset(); }
|
||||||
|
|
||||||
|
void reset() noexcept
|
||||||
|
{
|
||||||
|
if (tag == String)
|
||||||
|
destruct(u.s);
|
||||||
|
tag = Nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(float value) noexcept
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
u.f = value;
|
||||||
|
tag = Float;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(std::string value) noexcept
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
new (&u.s) std::string(std::move(value));
|
||||||
|
tag = String;
|
||||||
|
}
|
||||||
|
|
||||||
|
float to_float() const
|
||||||
|
{
|
||||||
|
if (tag != Float)
|
||||||
|
throw std::runtime_error("the tagged union does not contain `float`");
|
||||||
|
return u.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& to_string() const
|
||||||
|
{
|
||||||
|
if (tag != String)
|
||||||
|
throw std::runtime_error("the tagged union does not contain `string`");
|
||||||
|
return u.s;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <class T> static void destruct(T& obj) { obj.~T(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum TypeTag { Nil, Float, String };
|
||||||
|
union Union {
|
||||||
|
constexpr explicit Union(float f = 0.0f) noexcept : f(f) {}
|
||||||
|
~Union() noexcept {}
|
||||||
|
float f;
|
||||||
|
std::string s;
|
||||||
|
};
|
||||||
|
TypeTag tag { Nil };
|
||||||
|
Union u;
|
||||||
|
};
|
||||||
1175
editor/src/editor/Editor.cpp
Normal file
30
editor/src/editor/Editor.h
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <memory>
|
||||||
|
class EditorController;
|
||||||
|
|
||||||
|
#include "utility/vstgui_before.h"
|
||||||
|
#include "vstgui/lib/vstguifwd.h"
|
||||||
|
#include "utility/vstgui_after.h"
|
||||||
|
using VSTGUI::CFrame;
|
||||||
|
|
||||||
|
class Editor {
|
||||||
|
public:
|
||||||
|
static const int viewWidth;
|
||||||
|
static const int viewHeight;
|
||||||
|
|
||||||
|
explicit Editor(EditorController& ctrl);
|
||||||
|
~Editor();
|
||||||
|
|
||||||
|
void open(CFrame& frame);
|
||||||
|
void close();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Impl;
|
||||||
|
std::unique_ptr<Impl> impl_;
|
||||||
|
};
|
||||||
43
editor/src/editor/EditorController.h
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "EditValue.h"
|
||||||
|
#include <absl/strings/string_view.h>
|
||||||
|
#include <string>
|
||||||
|
#include <cstdint>
|
||||||
|
enum class EditId : int;
|
||||||
|
|
||||||
|
class EditorController {
|
||||||
|
public:
|
||||||
|
virtual ~EditorController() {}
|
||||||
|
|
||||||
|
// called by Editor
|
||||||
|
virtual void uiSendValue(EditId id, const EditValue& v) = 0;
|
||||||
|
virtual void uiBeginSend(EditId id) = 0;
|
||||||
|
virtual void uiEndSend(EditId id) = 0;
|
||||||
|
virtual void uiSendMIDI(const uint8_t* msg, uint32_t len) = 0;
|
||||||
|
class Receiver;
|
||||||
|
void decorate(Receiver* r) { r_ = r; }
|
||||||
|
|
||||||
|
class Receiver {
|
||||||
|
public:
|
||||||
|
virtual ~Receiver() {}
|
||||||
|
virtual void uiReceiveValue(EditId id, const EditValue& v) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// called by DSP
|
||||||
|
void uiReceiveValue(EditId id, const EditValue& v);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Receiver* r_ = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void EditorController::uiReceiveValue(EditId id, const EditValue& v)
|
||||||
|
{
|
||||||
|
if (r_)
|
||||||
|
r_->uiReceiveValue(id, v);
|
||||||
|
}
|
||||||
495
editor/src/editor/GUIComponents.cpp
Normal file
|
|
@ -0,0 +1,495 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#include "GUIComponents.h"
|
||||||
|
#include <complex>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#include "utility/vstgui_before.h"
|
||||||
|
#include "vstgui/lib/cdrawcontext.h"
|
||||||
|
#include "vstgui/lib/cgraphicspath.h"
|
||||||
|
#include "vstgui/lib/cframe.h"
|
||||||
|
#include "utility/vstgui_after.h"
|
||||||
|
|
||||||
|
///
|
||||||
|
SBoxContainer::SBoxContainer(const CRect& size)
|
||||||
|
: CViewContainer(size)
|
||||||
|
{
|
||||||
|
CViewContainer::setBackgroundColor(CColor(0, 0, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SBoxContainer::setCornerRadius(CCoord radius)
|
||||||
|
{
|
||||||
|
cornerRadius_ = radius;
|
||||||
|
invalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SBoxContainer::setBackgroundColor(const CColor& color)
|
||||||
|
{
|
||||||
|
backgroundColor_ = color;
|
||||||
|
invalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
CColor SBoxContainer::getBackgroundColor() const
|
||||||
|
{
|
||||||
|
return backgroundColor_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SBoxContainer::drawRect(CDrawContext* dc, const CRect& updateRect)
|
||||||
|
{
|
||||||
|
CRect bounds = getViewSize();
|
||||||
|
|
||||||
|
dc->setDrawMode(kAntiAliasing);
|
||||||
|
|
||||||
|
SharedPointer<CGraphicsPath> path = owned(dc->createGraphicsPath());
|
||||||
|
path->addRoundRect(bounds, cornerRadius_);
|
||||||
|
|
||||||
|
dc->setFillColor(backgroundColor_);
|
||||||
|
dc->drawGraphicsPath(path.get(), CDrawContext::kPathFilled);
|
||||||
|
|
||||||
|
CViewContainer::drawRect(dc, updateRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
STitleContainer::STitleContainer(const CRect& size, UTF8StringPtr text)
|
||||||
|
: SBoxContainer(size), text_(text ? text : ""), titleFont_(kNormalFont)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void STitleContainer::setTitleFont(CFontRef font)
|
||||||
|
{
|
||||||
|
titleFont_ = font;
|
||||||
|
invalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void STitleContainer::setTitleFontColor(CColor color)
|
||||||
|
{
|
||||||
|
titleFontColor_ = color;
|
||||||
|
invalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void STitleContainer::setTitleBackgroundColor(CColor color)
|
||||||
|
{
|
||||||
|
titleBackgroundColor_ = color;
|
||||||
|
invalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void STitleContainer::drawRect(CDrawContext* dc, const CRect& updateRect)
|
||||||
|
{
|
||||||
|
SBoxContainer::drawRect(dc, updateRect);
|
||||||
|
|
||||||
|
CRect bounds = getViewSize();
|
||||||
|
CCoord cornerRadius = cornerRadius_;
|
||||||
|
|
||||||
|
dc->setDrawMode(kAntiAliasing);
|
||||||
|
|
||||||
|
CCoord fontHeight = titleFont_->getSize();
|
||||||
|
CCoord titleHeight = fontHeight + 8.0;
|
||||||
|
|
||||||
|
CRect titleBounds = bounds;
|
||||||
|
titleBounds.bottom = titleBounds.top + titleHeight;
|
||||||
|
|
||||||
|
SharedPointer<CGraphicsPath> path = owned(dc->createGraphicsPath());
|
||||||
|
path->beginSubpath(titleBounds.getBottomRight());
|
||||||
|
path->addLine(titleBounds.getBottomLeft());
|
||||||
|
path->addArc(CRect(titleBounds.left, titleBounds.top, titleBounds.left + 2.0 * cornerRadius, titleBounds.top + 2.0 * cornerRadius), 180., 270., true);
|
||||||
|
path->addArc(CRect(titleBounds.right - 2.0 * cornerRadius, titleBounds.top, titleBounds.right, titleBounds.top + 2.0 * cornerRadius), 270., 360., true);
|
||||||
|
path->closeSubpath();
|
||||||
|
|
||||||
|
dc->setFillColor(titleBackgroundColor_);
|
||||||
|
dc->drawGraphicsPath(path, CDrawContext::kPathFilled);
|
||||||
|
|
||||||
|
dc->setFont(titleFont_);
|
||||||
|
dc->setFontColor(titleFontColor_);
|
||||||
|
dc->drawString(text_.c_str(), titleBounds, kCenterText);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
void SFileDropTarget::setFileDropFunction(FileDropFunction f)
|
||||||
|
{
|
||||||
|
dropFunction_ = std::move(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
DragOperation SFileDropTarget::onDragEnter(DragEventData data)
|
||||||
|
{
|
||||||
|
op_ = isFileDrop(data.drag) ?
|
||||||
|
DragOperation::Copy : DragOperation::None;
|
||||||
|
return op_;
|
||||||
|
}
|
||||||
|
|
||||||
|
DragOperation SFileDropTarget::onDragMove(DragEventData data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
return op_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SFileDropTarget::onDragLeave(DragEventData data)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
op_ = DragOperation::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SFileDropTarget::onDrop(DragEventData data)
|
||||||
|
{
|
||||||
|
if (op_ != DragOperation::Copy || !isFileDrop(data.drag))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
IDataPackage::Type type;
|
||||||
|
const void* bytes;
|
||||||
|
uint32_t size = data.drag->getData(0, bytes, type);
|
||||||
|
std::string path(reinterpret_cast<const char*>(bytes), size);
|
||||||
|
|
||||||
|
if (dropFunction_)
|
||||||
|
dropFunction_(path);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SFileDropTarget::isFileDrop(IDataPackage* package)
|
||||||
|
{
|
||||||
|
return package->getCount() == 1 &&
|
||||||
|
package->getDataType(0) == IDataPackage::kFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
SValueMenu::SValueMenu(const CRect& bounds, IControlListener* listener, int32_t tag)
|
||||||
|
: CParamDisplay(bounds), menuListener_(owned(new MenuListener(*this)))
|
||||||
|
{
|
||||||
|
setListener(listener);
|
||||||
|
setTag(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMenuItem* SValueMenu::addEntry(CMenuItem* item, float value, int32_t index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index > getNbEntries()) {
|
||||||
|
menuItems_.emplace_back(owned(item));
|
||||||
|
menuItemValues_.emplace_back(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
menuItems_.insert(menuItems_.begin() + index, owned(item));
|
||||||
|
menuItemValues_.insert(menuItemValues_.begin() + index, value);
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
CMenuItem* SValueMenu::addEntry(const UTF8String& title, float value, int32_t index, int32_t itemFlags)
|
||||||
|
{
|
||||||
|
if (title == "-")
|
||||||
|
return addSeparator(index);
|
||||||
|
CMenuItem* item = new CMenuItem(title, nullptr, 0, nullptr, itemFlags);
|
||||||
|
return addEntry(item, value, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMenuItem* SValueMenu::addSeparator(int32_t index)
|
||||||
|
{
|
||||||
|
CMenuItem* item = new CMenuItem("", nullptr, 0, nullptr, CMenuItem::kSeparator);
|
||||||
|
return addEntry(item, 0.0f, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t SValueMenu::getNbEntries() const
|
||||||
|
{
|
||||||
|
return static_cast<int32_t>(menuItems_.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
CMouseEventResult SValueMenu::onMouseDown(CPoint& where, const CButtonState& buttons)
|
||||||
|
{
|
||||||
|
(void)where;
|
||||||
|
|
||||||
|
if (buttons & (kLButton|kRButton|kApple)) {
|
||||||
|
CFrame* frame = getFrame();
|
||||||
|
CRect bounds = getViewSize();
|
||||||
|
|
||||||
|
CPoint frameWhere = bounds.getBottomLeft();
|
||||||
|
this->localToFrame(frameWhere);
|
||||||
|
|
||||||
|
auto self = shared(this);
|
||||||
|
frame->doAfterEventProcessing([self, frameWhere]() {
|
||||||
|
if (CFrame* frame = self->getFrame()) {
|
||||||
|
SharedPointer<COptionMenu> menu = owned(new COptionMenu(CRect(), self->menuListener_, -1, nullptr, nullptr, COptionMenu::kPopupStyle));
|
||||||
|
for (const SharedPointer<CMenuItem>& item : self->menuItems_) {
|
||||||
|
menu->addEntry(item);
|
||||||
|
item->remember(); // above call does not increment refcount
|
||||||
|
}
|
||||||
|
menu->setFont(self->getFont());
|
||||||
|
menu->setFontColor(self->getFontColor());
|
||||||
|
menu->setBackColor(self->getBackColor());
|
||||||
|
menu->popup(frame, frameWhere + CPoint(0.0, 1.0));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return kMouseDownEventHandledButDontNeedMovedOrUpEvents;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kMouseEventNotHandled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SValueMenu::onItemClicked(int32_t index)
|
||||||
|
{
|
||||||
|
float oldValue = getValue();
|
||||||
|
setValue(menuItemValues_[index]);
|
||||||
|
if (getValue() != oldValue)
|
||||||
|
valueChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
SActionMenu::SActionMenu(const CRect& bounds, IControlListener* listener)
|
||||||
|
: CParamDisplay(bounds), menuListener_(owned(new MenuListener(*this)))
|
||||||
|
{
|
||||||
|
setListener(listener);
|
||||||
|
|
||||||
|
auto toString = [](float, std::string& result, CParamDisplay* display) {
|
||||||
|
result = static_cast<SActionMenu*>(display)->getTitle();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
setValueToStringFunction2(toString);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SActionMenu::setTitle(std::string title)
|
||||||
|
{
|
||||||
|
title_ = std::move(title);
|
||||||
|
invalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SActionMenu::setHoverColor(const CColor& color)
|
||||||
|
{
|
||||||
|
hoverColor_ = color;
|
||||||
|
invalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
CMenuItem* SActionMenu::addEntry(CMenuItem* item, int32_t tag, int32_t index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index > getNbEntries()) {
|
||||||
|
menuItems_.emplace_back(owned(item));
|
||||||
|
menuItemTags_.emplace_back(tag);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
menuItems_.insert(menuItems_.begin() + index, owned(item));
|
||||||
|
menuItemTags_.insert(menuItemTags_.begin() + index, tag);
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
CMenuItem* SActionMenu::addEntry(const UTF8String& title, int32_t tag, int32_t index, int32_t itemFlags)
|
||||||
|
{
|
||||||
|
if (title == "-")
|
||||||
|
return addSeparator(index);
|
||||||
|
CMenuItem* item = new CMenuItem(title, nullptr, 0, nullptr, itemFlags);
|
||||||
|
return addEntry(item, tag, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMenuItem* SActionMenu::addSeparator(int32_t index)
|
||||||
|
{
|
||||||
|
CMenuItem* item = new CMenuItem("", nullptr, 0, nullptr, CMenuItem::kSeparator);
|
||||||
|
return addEntry(item, 0.0f, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t SActionMenu::getNbEntries() const
|
||||||
|
{
|
||||||
|
return static_cast<int32_t>(menuItems_.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SActionMenu::draw(CDrawContext* dc)
|
||||||
|
{
|
||||||
|
CColor backupColor = fontColor;
|
||||||
|
if (hovered_)
|
||||||
|
fontColor = hoverColor_;
|
||||||
|
CParamDisplay::draw(dc);
|
||||||
|
if (hovered_)
|
||||||
|
fontColor = backupColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
CMouseEventResult SActionMenu::onMouseEntered(CPoint& where, const CButtonState& buttons)
|
||||||
|
{
|
||||||
|
hovered_ = true;
|
||||||
|
invalid();
|
||||||
|
return CParamDisplay::onMouseEntered(where, buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMouseEventResult SActionMenu::onMouseExited(CPoint& where, const CButtonState& buttons)
|
||||||
|
{
|
||||||
|
hovered_ = false;
|
||||||
|
invalid();
|
||||||
|
return CParamDisplay::onMouseExited(where, buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMouseEventResult SActionMenu::onMouseDown(CPoint& where, const CButtonState& buttons)
|
||||||
|
{
|
||||||
|
(void)where;
|
||||||
|
|
||||||
|
if (buttons & (kLButton|kRButton|kApple)) {
|
||||||
|
CFrame* frame = getFrame();
|
||||||
|
CRect bounds = getViewSize();
|
||||||
|
|
||||||
|
CPoint frameWhere = bounds.getBottomLeft();
|
||||||
|
this->localToFrame(frameWhere);
|
||||||
|
|
||||||
|
auto self = shared(this);
|
||||||
|
frame->doAfterEventProcessing([self, frameWhere]() {
|
||||||
|
if (CFrame* frame = self->getFrame()) {
|
||||||
|
SharedPointer<COptionMenu> menu = owned(new COptionMenu(CRect(), self->menuListener_, -1, nullptr, nullptr, COptionMenu::kPopupStyle));
|
||||||
|
for (const SharedPointer<CMenuItem>& item : self->menuItems_) {
|
||||||
|
menu->addEntry(item);
|
||||||
|
item->remember(); // above call does not increment refcount
|
||||||
|
}
|
||||||
|
menu->setFont(self->getFont());
|
||||||
|
menu->setFontColor(self->getFontColor());
|
||||||
|
menu->setBackColor(self->getBackColor());
|
||||||
|
menu->popup(frame, frameWhere + CPoint(0.0, 1.0));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return kMouseDownEventHandledButDontNeedMovedOrUpEvents;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kMouseEventNotHandled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SActionMenu::onItemClicked(int32_t index)
|
||||||
|
{
|
||||||
|
setTag(menuItemTags_[index]);
|
||||||
|
setValue(1.0f);
|
||||||
|
if (listener)
|
||||||
|
listener->valueChanged(this);
|
||||||
|
setValue(0.0f);
|
||||||
|
if (listener)
|
||||||
|
listener->valueChanged(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
void STextButton::setHoverColor(const CColor& color)
|
||||||
|
{
|
||||||
|
hoverColor_ = color;
|
||||||
|
invalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void STextButton::setInactiveColor(const CColor& color)
|
||||||
|
{
|
||||||
|
inactiveColor_ = color;
|
||||||
|
invalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void STextButton::setInactive(bool b)
|
||||||
|
{
|
||||||
|
inactive_ = b;
|
||||||
|
invalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void STextButton::draw(CDrawContext* context)
|
||||||
|
{
|
||||||
|
CColor backupColor = textColor;
|
||||||
|
if (hovered_)
|
||||||
|
textColor = hoverColor_; // textColor is protected
|
||||||
|
else if (inactive_)
|
||||||
|
textColor = inactiveColor_;
|
||||||
|
CTextButton::draw(context);
|
||||||
|
textColor = backupColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CMouseEventResult STextButton::onMouseEntered (CPoint& where, const CButtonState& buttons)
|
||||||
|
{
|
||||||
|
hovered_ = true;
|
||||||
|
invalid();
|
||||||
|
return CTextButton::onMouseEntered(where, buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMouseEventResult STextButton::onMouseExited (CPoint& where, const CButtonState& buttons)
|
||||||
|
{
|
||||||
|
hovered_ = false;
|
||||||
|
invalid();
|
||||||
|
return CTextButton::onMouseExited(where, buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
SStyledKnob::SStyledKnob(const CRect& size, IControlListener* listener, int32_t tag)
|
||||||
|
: CKnobBase(size, listener, tag, nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SStyledKnob::setActiveTrackColor(const CColor& color)
|
||||||
|
{
|
||||||
|
if (activeTrackColor_ == color)
|
||||||
|
return;
|
||||||
|
activeTrackColor_ = color;
|
||||||
|
invalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SStyledKnob::setInactiveTrackColor(const CColor& color)
|
||||||
|
{
|
||||||
|
if (inactiveTrackColor_ == color)
|
||||||
|
return;
|
||||||
|
inactiveTrackColor_ = color;
|
||||||
|
invalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SStyledKnob::setLineIndicatorColor(const CColor& color)
|
||||||
|
{
|
||||||
|
if (lineIndicatorColor_ == color)
|
||||||
|
return;
|
||||||
|
lineIndicatorColor_ = color;
|
||||||
|
invalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SStyledKnob::draw(CDrawContext* dc)
|
||||||
|
{
|
||||||
|
const CCoord lineWidth = 4.0;
|
||||||
|
const CCoord indicatorLineLength = 10.0;
|
||||||
|
const CCoord angleSpread = 250.0;
|
||||||
|
const CCoord angle1 = 270.0 - 0.5 * angleSpread;
|
||||||
|
const CCoord angle2 = 270.0 + 0.5 * angleSpread;
|
||||||
|
|
||||||
|
dc->setDrawMode(kAntiAliasing);
|
||||||
|
|
||||||
|
const CRect bounds = getViewSize();
|
||||||
|
|
||||||
|
// compute inner bounds
|
||||||
|
CRect rect(bounds);
|
||||||
|
rect.setWidth(std::min(rect.getWidth(), rect.getHeight()));
|
||||||
|
rect.setHeight(rect.getWidth());
|
||||||
|
rect.centerInside(bounds);
|
||||||
|
rect.extend(-lineWidth, -lineWidth);
|
||||||
|
|
||||||
|
SharedPointer<CGraphicsPath> path;
|
||||||
|
|
||||||
|
// inactive track
|
||||||
|
path = owned(dc->createGraphicsPath());
|
||||||
|
path->addArc(rect, angle1, angle2, true);
|
||||||
|
|
||||||
|
dc->setFrameColor(inactiveTrackColor_);
|
||||||
|
dc->setLineWidth(lineWidth);
|
||||||
|
dc->setLineStyle(kLineSolid);
|
||||||
|
dc->drawGraphicsPath(path, CDrawContext::kPathStroked);
|
||||||
|
|
||||||
|
// active track
|
||||||
|
const CCoord v = getValueNormalized();
|
||||||
|
const CCoord vAngle = angle1 + v * angleSpread;
|
||||||
|
path = owned(dc->createGraphicsPath());
|
||||||
|
path->addArc(rect, angle1, vAngle, true);
|
||||||
|
|
||||||
|
dc->setFrameColor(activeTrackColor_);
|
||||||
|
dc->setLineWidth(lineWidth + 0.5);
|
||||||
|
dc->setLineStyle(kLineSolid);
|
||||||
|
dc->drawGraphicsPath(path, CDrawContext::kPathStroked);
|
||||||
|
|
||||||
|
// indicator line
|
||||||
|
{
|
||||||
|
CCoord module1 = 0.5 * rect.getWidth() - indicatorLineLength;
|
||||||
|
CCoord module2 = 0.5 * rect.getWidth();
|
||||||
|
std::complex<CCoord> c1 = std::polar(module1, vAngle * (M_PI / 180.0));
|
||||||
|
std::complex<CCoord> c2 = std::polar(module2, vAngle * (M_PI / 180.0));
|
||||||
|
|
||||||
|
CPoint p1(c1.real(), c1.imag());
|
||||||
|
CPoint p2(c2.real(), c2.imag());
|
||||||
|
p1.offset(rect.getCenter());
|
||||||
|
p2.offset(rect.getCenter());
|
||||||
|
|
||||||
|
dc->setFrameColor(lineIndicatorColor_);
|
||||||
|
dc->setLineWidth(1.0);
|
||||||
|
dc->setLineStyle(kLineSolid);
|
||||||
|
dc->drawLine(p1, p2);
|
||||||
|
}
|
||||||
|
}
|
||||||
210
editor/src/editor/GUIComponents.h
Normal file
|
|
@ -0,0 +1,210 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
|
#include "utility/vstgui_before.h"
|
||||||
|
#include "vstgui/lib/controls/cslider.h"
|
||||||
|
#include "vstgui/lib/controls/cknob.h"
|
||||||
|
#include "vstgui/lib/controls/ctextlabel.h"
|
||||||
|
#include "vstgui/lib/controls/cbuttons.h"
|
||||||
|
#include "vstgui/lib/controls/coptionmenu.h"
|
||||||
|
#include "vstgui/lib/cviewcontainer.h"
|
||||||
|
#include "vstgui/lib/ccolor.h"
|
||||||
|
#include "vstgui/lib/dragging.h"
|
||||||
|
#include "utility/vstgui_after.h"
|
||||||
|
|
||||||
|
using namespace VSTGUI;
|
||||||
|
|
||||||
|
///
|
||||||
|
class SBoxContainer : public CViewContainer {
|
||||||
|
public:
|
||||||
|
explicit SBoxContainer(const CRect& size);
|
||||||
|
virtual ~SBoxContainer() {}
|
||||||
|
void setCornerRadius(CCoord radius);
|
||||||
|
void setBackgroundColor(const CColor& color) override;
|
||||||
|
CColor getBackgroundColor() const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void drawRect(CDrawContext* dc, const CRect& updateRect) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CCoord cornerRadius_ = 0.0;
|
||||||
|
CColor backgroundColor_;
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
class STitleContainer : public SBoxContainer {
|
||||||
|
public:
|
||||||
|
explicit STitleContainer(const CRect& size, UTF8StringPtr text = nullptr);
|
||||||
|
~STitleContainer() {}
|
||||||
|
|
||||||
|
void setTitleFont(CFontRef font);
|
||||||
|
CFontRef getTitleFont() { return titleFont_; }
|
||||||
|
|
||||||
|
void setTitleFontColor(CColor color);
|
||||||
|
CColor getTitleFontColor() const { return titleFontColor_; }
|
||||||
|
void setTitleBackgroundColor(CColor color);
|
||||||
|
CColor getTitleBackgroundColor() const { return titleBackgroundColor_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void drawRect(CDrawContext* dc, const CRect& updateRect) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string text_;
|
||||||
|
CColor titleFontColor_;
|
||||||
|
CColor titleBackgroundColor_;
|
||||||
|
SharedPointer<CFontDesc> titleFont_;
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
class SFileDropTarget : public IDropTarget,
|
||||||
|
public NonAtomicReferenceCounted {
|
||||||
|
public:
|
||||||
|
typedef std::function<void(const std::string&)> FileDropFunction;
|
||||||
|
void setFileDropFunction(FileDropFunction f);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DragOperation onDragEnter(DragEventData data) override;
|
||||||
|
DragOperation onDragMove(DragEventData data) override;
|
||||||
|
void onDragLeave(DragEventData data) override;
|
||||||
|
bool onDrop(DragEventData data) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool isFileDrop(IDataPackage* package);
|
||||||
|
|
||||||
|
private:
|
||||||
|
DragOperation op_ = DragOperation::None;
|
||||||
|
FileDropFunction dropFunction_;
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
class SValueMenu : public CParamDisplay {
|
||||||
|
public:
|
||||||
|
explicit SValueMenu(const CRect& bounds, IControlListener* listener, int32_t tag);
|
||||||
|
CMenuItem* addEntry(CMenuItem* item, float value, int32_t index = -1);
|
||||||
|
CMenuItem* addEntry(const UTF8String& title, float value, int32_t index = -1, int32_t itemFlags = CMenuItem::kNoFlags);
|
||||||
|
CMenuItem* addSeparator(int32_t index = -1);
|
||||||
|
int32_t getNbEntries() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CMouseEventResult onMouseDown(CPoint& where, const CButtonState& buttons) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
class MenuListener;
|
||||||
|
|
||||||
|
//
|
||||||
|
void onItemClicked(int32_t index);
|
||||||
|
|
||||||
|
//
|
||||||
|
CMenuItemList menuItems_;
|
||||||
|
std::vector<float> menuItemValues_;
|
||||||
|
SharedPointer<MenuListener> menuListener_;
|
||||||
|
|
||||||
|
//
|
||||||
|
class MenuListener : public IControlListener, public NonAtomicReferenceCounted {
|
||||||
|
public:
|
||||||
|
explicit MenuListener(SValueMenu& menu) : menu_(menu) {}
|
||||||
|
void valueChanged(CControl* control) override
|
||||||
|
{
|
||||||
|
menu_.onItemClicked(static_cast<int32_t>(control->getValue()));
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
SValueMenu& menu_;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
class SActionMenu : public CParamDisplay {
|
||||||
|
public:
|
||||||
|
explicit SActionMenu(const CRect& bounds, IControlListener* listener);
|
||||||
|
std::string getTitle() const { return title_; }
|
||||||
|
void setTitle(std::string title);
|
||||||
|
CColor getHoverColor() const { return hoverColor_; }
|
||||||
|
void setHoverColor(const CColor& color);
|
||||||
|
CMenuItem* addEntry(CMenuItem* item, int32_t tag, int32_t index = -1);
|
||||||
|
CMenuItem* addEntry(const UTF8String& title, int32_t tag, int32_t index = -1, int32_t itemFlags = CMenuItem::kNoFlags);
|
||||||
|
CMenuItem* addSeparator(int32_t index = -1);
|
||||||
|
int32_t getNbEntries() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void draw(CDrawContext* dc) override;
|
||||||
|
CMouseEventResult onMouseEntered(CPoint& where, const CButtonState& buttons) override;
|
||||||
|
CMouseEventResult onMouseExited(CPoint& where, const CButtonState& buttons) override;
|
||||||
|
CMouseEventResult onMouseDown(CPoint& where, const CButtonState& buttons) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string title_;
|
||||||
|
CColor hoverColor_;
|
||||||
|
bool hovered_ = false;
|
||||||
|
|
||||||
|
class MenuListener;
|
||||||
|
|
||||||
|
//
|
||||||
|
void onItemClicked(int32_t index);
|
||||||
|
|
||||||
|
//
|
||||||
|
CMenuItemList menuItems_;
|
||||||
|
std::vector<int32_t> menuItemTags_;
|
||||||
|
SharedPointer<MenuListener> menuListener_;
|
||||||
|
|
||||||
|
//
|
||||||
|
class MenuListener : public IControlListener, public NonAtomicReferenceCounted {
|
||||||
|
public:
|
||||||
|
explicit MenuListener(SActionMenu& menu) : menu_(menu) {}
|
||||||
|
void valueChanged(CControl* control) override
|
||||||
|
{
|
||||||
|
menu_.onItemClicked(static_cast<int32_t>(control->getValue()));
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
SActionMenu& menu_;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
class STextButton: public CTextButton {
|
||||||
|
public:
|
||||||
|
STextButton(const CRect& size, IControlListener* listener = nullptr, int32_t tag = -1, UTF8StringPtr title = nullptr)
|
||||||
|
: CTextButton(size, listener, tag, title) {}
|
||||||
|
|
||||||
|
CColor getHoverColor() const { return hoverColor_; }
|
||||||
|
void setHoverColor(const CColor& color);
|
||||||
|
CColor getInactiveColor() const { return inactiveColor_; }
|
||||||
|
void setInactiveColor(const CColor& color);
|
||||||
|
bool isInactive() const { return inactive_; }
|
||||||
|
void setInactive(bool b);
|
||||||
|
CMouseEventResult onMouseEntered (CPoint& where, const CButtonState& buttons) override;
|
||||||
|
CMouseEventResult onMouseExited (CPoint& where, const CButtonState& buttons) override;
|
||||||
|
void draw(CDrawContext* context) override;
|
||||||
|
private:
|
||||||
|
CColor hoverColor_;
|
||||||
|
bool hovered_ { false };
|
||||||
|
CColor inactiveColor_;
|
||||||
|
bool inactive_ { false };
|
||||||
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
class SStyledKnob : public CKnobBase {
|
||||||
|
public:
|
||||||
|
SStyledKnob(const CRect& size, IControlListener* listener, int32_t tag);
|
||||||
|
|
||||||
|
const CColor& getActiveTrackColor() const { return activeTrackColor_; }
|
||||||
|
void setActiveTrackColor(const CColor& color);
|
||||||
|
const CColor& getInactiveTrackColor() const { return inactiveTrackColor_; }
|
||||||
|
void setInactiveTrackColor(const CColor& color);
|
||||||
|
const CColor& getLineIndicatorColor() const { return lineIndicatorColor_; }
|
||||||
|
void setLineIndicatorColor(const CColor& color);
|
||||||
|
|
||||||
|
CLASS_METHODS(SStyledKnob, CKnobBase)
|
||||||
|
protected:
|
||||||
|
void draw(CDrawContext* dc) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CColor activeTrackColor_;
|
||||||
|
CColor inactiveTrackColor_;
|
||||||
|
CColor lineIndicatorColor_;
|
||||||
|
};
|
||||||
238
editor/src/editor/GUIPiano.cpp
Normal file
|
|
@ -0,0 +1,238 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#include "GUIPiano.h"
|
||||||
|
#include "utility/vstgui_before.h"
|
||||||
|
#include "vstgui/lib/cdrawcontext.h"
|
||||||
|
#include "vstgui/lib/cgraphicspath.h"
|
||||||
|
#include "utility/vstgui_after.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
static constexpr CCoord keyoffs[12] = {0, 0.6, 1, 1.8, 2, 3,
|
||||||
|
3.55, 4, 4.7, 5, 5.85, 6};
|
||||||
|
static constexpr bool black[12] = {0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0};
|
||||||
|
|
||||||
|
SPiano::SPiano(CRect bounds)
|
||||||
|
: CView(bounds)
|
||||||
|
{
|
||||||
|
setNumOctaves(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPiano::setFont(CFontRef font)
|
||||||
|
{
|
||||||
|
font_ = font;
|
||||||
|
getDimensions(true);
|
||||||
|
invalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPiano::setNumOctaves(unsigned octs)
|
||||||
|
{
|
||||||
|
keyval_.resize(octs * 12);
|
||||||
|
octs_ = std::max(1u, octs);
|
||||||
|
getDimensions(true);
|
||||||
|
invalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SPiano::draw(CDrawContext* dc)
|
||||||
|
{
|
||||||
|
const Dimensions dim = getDimensions(false);
|
||||||
|
const unsigned octs = octs_;
|
||||||
|
const unsigned keyCount = octs * 12;
|
||||||
|
|
||||||
|
dc->setDrawMode(kAntiAliasing);
|
||||||
|
|
||||||
|
if (backgroundFill_.alpha > 0) {
|
||||||
|
SharedPointer<CGraphicsPath> path;
|
||||||
|
path = owned(dc->createGraphicsPath());
|
||||||
|
path->addRoundRect(dim.bounds, backgroundRadius_);
|
||||||
|
dc->setFillColor(CColor(0xca, 0xca, 0xca));
|
||||||
|
dc->drawGraphicsPath(path, CDrawContext::kPathFilled);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned key = 0; key < keyCount; ++key) {
|
||||||
|
if (!black[key % 12]) {
|
||||||
|
CRect rect = keyRect(key);
|
||||||
|
CColor keycolor = whiteFill_;
|
||||||
|
if (keyval_[key])
|
||||||
|
keycolor = pressedFill_;
|
||||||
|
dc->setFillColor(keycolor);
|
||||||
|
dc->drawRect(rect, kDrawFilled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dc->setFrameColor(outline_);
|
||||||
|
dc->drawLine(dim.keyBounds.getTopLeft(), dim.keyBounds.getBottomLeft());
|
||||||
|
for (unsigned key = 0; key < keyCount; ++key) {
|
||||||
|
if (!black[key % 12]) {
|
||||||
|
CRect rect = keyRect(key);
|
||||||
|
dc->drawLine(rect.getTopRight(), rect.getBottomRight());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned key = 0; key < keyCount; ++key) {
|
||||||
|
if (black[key % 12]) {
|
||||||
|
CRect rect = keyRect(key);
|
||||||
|
CColor keycolor = blackFill_;
|
||||||
|
if (keyval_[key])
|
||||||
|
keycolor = pressedFill_;
|
||||||
|
dc->setFillColor(keycolor);
|
||||||
|
dc->drawRect(rect, kDrawFilled);
|
||||||
|
dc->setFrameColor(outline_);
|
||||||
|
dc->drawRect(rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const CFontRef& font = font_) {
|
||||||
|
for (unsigned o = 0; o < octs; ++o) {
|
||||||
|
CRect rect = keyRect(o * 12);
|
||||||
|
CRect textRect(
|
||||||
|
rect.left, dim.labelBounds.top,
|
||||||
|
rect.right, dim.labelBounds.bottom);
|
||||||
|
dc->setFont(font_);
|
||||||
|
dc->setFontColor(labelStroke_);
|
||||||
|
std::string text = std::to_string(static_cast<int>(o) - 1);
|
||||||
|
dc->drawString(text.c_str(), textRect, kCenterText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
dc->setFrameColor(outline_);
|
||||||
|
dc->drawLine(dim.keyBounds.getTopLeft(), dim.keyBounds.getTopRight());
|
||||||
|
dc->setFrameColor(shadeOutline_);
|
||||||
|
dc->drawLine(dim.keyBounds.getBottomLeft(), dim.keyBounds.getBottomRight());
|
||||||
|
}
|
||||||
|
|
||||||
|
dc->setFrameColor(outline_);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMouseEventResult SPiano::onMouseDown(CPoint& where, const CButtonState& buttons)
|
||||||
|
{
|
||||||
|
unsigned key = keyAtPos(where);
|
||||||
|
if (key != ~0u) {
|
||||||
|
keyval_[key] = 1;
|
||||||
|
mousePressedKey_ = key;
|
||||||
|
if (onKeyPressed)
|
||||||
|
onKeyPressed(key, mousePressVelocity(key, where.y));
|
||||||
|
invalid();
|
||||||
|
return kMouseEventHandled;
|
||||||
|
}
|
||||||
|
return CView::onMouseDown(where, buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMouseEventResult SPiano::onMouseUp(CPoint& where, const CButtonState& buttons)
|
||||||
|
{
|
||||||
|
unsigned key = mousePressedKey_;
|
||||||
|
if (key != ~0u) {
|
||||||
|
keyval_[key] = 0;
|
||||||
|
if (onKeyReleased)
|
||||||
|
onKeyReleased(key, mousePressVelocity(key, where.y));
|
||||||
|
mousePressedKey_ = ~0u;
|
||||||
|
invalid();
|
||||||
|
return kMouseEventHandled;
|
||||||
|
}
|
||||||
|
return CView::onMouseUp(where, buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
CMouseEventResult SPiano::onMouseMoved(CPoint& where, const CButtonState& buttons)
|
||||||
|
{
|
||||||
|
if (mousePressedKey_ != ~0u) {
|
||||||
|
unsigned key = keyAtPos(where);
|
||||||
|
if (mousePressedKey_ != key) {
|
||||||
|
keyval_[mousePressedKey_] = 0;
|
||||||
|
if (onKeyReleased)
|
||||||
|
onKeyReleased(mousePressedKey_, mousePressVelocity(key, where.y));
|
||||||
|
// mousePressedKey_ = ~0u;
|
||||||
|
if (key != ~0u) {
|
||||||
|
keyval_[key] = 1;
|
||||||
|
mousePressedKey_ = key;
|
||||||
|
if (onKeyPressed)
|
||||||
|
onKeyPressed(key, mousePressVelocity(key, where.y));
|
||||||
|
}
|
||||||
|
invalid();
|
||||||
|
}
|
||||||
|
return kMouseEventHandled;
|
||||||
|
}
|
||||||
|
return CView::onMouseMoved(where, buttons);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SPiano::Dimensions& SPiano::getDimensions(bool forceUpdate) const
|
||||||
|
{
|
||||||
|
if (!forceUpdate && dim_.bounds == getViewSize())
|
||||||
|
return dim_;
|
||||||
|
|
||||||
|
Dimensions dim;
|
||||||
|
dim.bounds = getViewSize();
|
||||||
|
dim.paddedBounds = CRect(dim.bounds)
|
||||||
|
.extend(-2 * innerPaddingX_, -2 * innerPaddingY_);
|
||||||
|
CCoord keyHeight = std::floor(dim.paddedBounds.getHeight());
|
||||||
|
CCoord fontHeight = font_ ? font_->getSize() : 0.0;
|
||||||
|
keyHeight -= spacingY_ + fontHeight;
|
||||||
|
dim.keyBounds = CRect(dim.paddedBounds)
|
||||||
|
.setHeight(keyHeight);
|
||||||
|
dim.keyWidth = static_cast<unsigned>(
|
||||||
|
dim.paddedBounds.getWidth() / octs_ / 7.0);
|
||||||
|
dim.keyBounds.setWidth(dim.keyWidth * octs_ * 7.0);
|
||||||
|
dim.keyBounds.offset(
|
||||||
|
std::floor(0.5 * (dim.paddedBounds.getWidth() - dim.keyBounds.getWidth())), 0.0);
|
||||||
|
|
||||||
|
if (!font_)
|
||||||
|
dim.labelBounds = CRect();
|
||||||
|
else
|
||||||
|
dim.labelBounds = CRect(
|
||||||
|
dim.keyBounds.left, dim.keyBounds.bottom + spacingY_,
|
||||||
|
dim.keyBounds.right, dim.keyBounds.bottom + spacingY_ + fontHeight);
|
||||||
|
|
||||||
|
dim_ = dim;
|
||||||
|
return dim_;
|
||||||
|
}
|
||||||
|
|
||||||
|
CRect SPiano::keyRect(const Dimensions& dim, unsigned key)
|
||||||
|
{
|
||||||
|
unsigned oct = key / 12;
|
||||||
|
unsigned note = key % 12;
|
||||||
|
unsigned keyw = dim.keyWidth;
|
||||||
|
unsigned keyh = static_cast<unsigned>(dim.keyBounds.getHeight());
|
||||||
|
CCoord octwidth = (keyoffs[11] + 1.0) * keyw;
|
||||||
|
CCoord octx = octwidth * oct;
|
||||||
|
CCoord notex = octx + keyoffs[note] * keyw;
|
||||||
|
CCoord notew = black[note] ? (0.6 * keyw) : keyw;
|
||||||
|
CCoord noteh = black[note] ? (0.6 * keyh) : keyh;
|
||||||
|
return CRect(notex, 0.0, notex + notew, noteh).offset(dim.keyBounds.getTopLeft());
|
||||||
|
}
|
||||||
|
|
||||||
|
CRect SPiano::keyRect(unsigned key) const
|
||||||
|
{
|
||||||
|
return keyRect(getDimensions(false), key);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned SPiano::keyAtPos(CPoint pos) const
|
||||||
|
{
|
||||||
|
const unsigned octs = octs_;
|
||||||
|
|
||||||
|
for (unsigned key = 0; key < octs * 12; ++key) {
|
||||||
|
if (black[key % 12]) {
|
||||||
|
if (keyRect(key).pointInside(pos))
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned key = 0; key < octs * 12; ++key) {
|
||||||
|
if (!black[key % 12]) {
|
||||||
|
if (keyRect(key).pointInside(pos))
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ~0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
float SPiano::mousePressVelocity(unsigned key, CCoord posY)
|
||||||
|
{
|
||||||
|
const CRect rect = keyRect(key);
|
||||||
|
CCoord value = (posY - rect.top) / rect.getHeight();
|
||||||
|
return std::max(0.0f, std::min(1.0f, static_cast<float>(value)));
|
||||||
|
}
|
||||||
72
editor/src/editor/GUIPiano.h
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "utility/vstgui_before.h"
|
||||||
|
#include "vstgui/lib/cview.h"
|
||||||
|
#include "vstgui/lib/ccolor.h"
|
||||||
|
#include "utility/vstgui_after.h"
|
||||||
|
#include <functional>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using namespace VSTGUI;
|
||||||
|
|
||||||
|
class SPiano : public CView {
|
||||||
|
public:
|
||||||
|
explicit SPiano(CRect bounds);
|
||||||
|
|
||||||
|
CFontRef getFont() const { return font_; }
|
||||||
|
void setFont(CFontRef font);
|
||||||
|
|
||||||
|
unsigned getNumOctaves() const { return octs_; }
|
||||||
|
void setNumOctaves(unsigned octs);
|
||||||
|
|
||||||
|
std::function<void(unsigned, float)> onKeyPressed;
|
||||||
|
std::function<void(unsigned, float)> onKeyReleased;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void draw(CDrawContext* dc) override;
|
||||||
|
CMouseEventResult onMouseDown(CPoint& where, const CButtonState& buttons) override;
|
||||||
|
CMouseEventResult onMouseUp(CPoint& where, const CButtonState& buttons) override;
|
||||||
|
CMouseEventResult onMouseMoved(CPoint& where, const CButtonState& buttons) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Dimensions {
|
||||||
|
CRect bounds {};
|
||||||
|
CRect paddedBounds {};
|
||||||
|
CRect keyBounds {};
|
||||||
|
unsigned keyWidth {};
|
||||||
|
CRect labelBounds {};
|
||||||
|
};
|
||||||
|
const Dimensions& getDimensions(bool forceUpdate) const;
|
||||||
|
|
||||||
|
static CRect keyRect(const Dimensions& dim, unsigned key);
|
||||||
|
CRect keyRect(unsigned key) const;
|
||||||
|
unsigned keyAtPos(CPoint pos) const;
|
||||||
|
|
||||||
|
float mousePressVelocity(unsigned key, CCoord posY);
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned octs_ {};
|
||||||
|
std::vector<unsigned> keyval_;
|
||||||
|
unsigned mousePressedKey_ = ~0u;
|
||||||
|
|
||||||
|
CCoord innerPaddingX_ = 4.0;
|
||||||
|
CCoord innerPaddingY_ = 4.0;
|
||||||
|
CCoord spacingY_ = 4.0;
|
||||||
|
|
||||||
|
CColor backgroundFill_ { 0xca, 0xca, 0xca, 0xff };
|
||||||
|
float backgroundRadius_ = 5.0;
|
||||||
|
CColor whiteFill_ { 0xee, 0xee, 0xec, 0xff };
|
||||||
|
CColor blackFill_ { 0x2e, 0x34, 0x36, 0xff };
|
||||||
|
CColor pressedFill_ { 0xa0, 0xa0, 0xa0, 0xff };
|
||||||
|
CColor outline_ { 0x00, 0x00, 0x00, 0xff };
|
||||||
|
CColor shadeOutline_ { 0x80, 0x80, 0x80, 0xff };
|
||||||
|
CColor labelStroke_ { 0x63, 0x63, 0x63, 0xff };
|
||||||
|
|
||||||
|
mutable Dimensions dim_;
|
||||||
|
SharedPointer<CFontDesc> font_;
|
||||||
|
};
|
||||||
50
editor/src/editor/NativeHelpers.cpp
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#include "NativeHelpers.h"
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#include "ghc/fs_std.hpp"
|
||||||
|
#include <windows.h>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
bool openFileInExternalEditor(const char *filename)
|
||||||
|
{
|
||||||
|
std::wstring path = fs::u8path(filename).wstring();
|
||||||
|
|
||||||
|
SHELLEXECUTEINFOW info;
|
||||||
|
memset(&info, 0, sizeof(info));
|
||||||
|
|
||||||
|
info.cbSize = sizeof(info);
|
||||||
|
info.fMask = SEE_MASK_CLASSNAME;
|
||||||
|
info.lpVerb = L"open";
|
||||||
|
info.lpFile = path.c_str();
|
||||||
|
info.lpClass = L"txtfile";
|
||||||
|
info.nShow = SW_SHOW;
|
||||||
|
|
||||||
|
return ShellExecuteExW(&info);
|
||||||
|
}
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
// implemented in NativeHelpers.mm
|
||||||
|
#else
|
||||||
|
#include <gio/gio.h>
|
||||||
|
|
||||||
|
bool openFileInExternalEditor(const char *filename)
|
||||||
|
{
|
||||||
|
GAppInfo* appinfo = g_app_info_get_default_for_type("text/plain", FALSE);
|
||||||
|
if (!appinfo)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
GList* files = nullptr;
|
||||||
|
GFile* file = g_file_new_for_path(filename);
|
||||||
|
files = g_list_append(files, file);
|
||||||
|
gboolean success = g_app_info_launch(appinfo, files, nullptr, nullptr);
|
||||||
|
g_object_unref(file);
|
||||||
|
g_list_free(files);
|
||||||
|
g_object_unref(appinfo);
|
||||||
|
return success == TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
9
editor/src/editor/NativeHelpers.h
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
bool openFileInExternalEditor(const char *filename);
|
||||||
30
editor/src/editor/NativeHelpers.mm
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#include "NativeHelpers.h"
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#import <AppKit/AppKit.h>
|
||||||
|
#import <CoreServices/CoreServices.h>
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
bool openFileInExternalEditor(const char *fileNameUTF8)
|
||||||
|
{
|
||||||
|
BOOL wasOpened = NO;
|
||||||
|
|
||||||
|
NSURL* applicationURL = (__bridge_transfer NSURL*)LSCopyDefaultApplicationURLForContentType(
|
||||||
|
kUTTypePlainText, kLSRolesEditor, nil);
|
||||||
|
if (!applicationURL)
|
||||||
|
return false;
|
||||||
|
if ([applicationURL isFileURL]) {
|
||||||
|
NSWorkspace* workspace = [NSWorkspace sharedWorkspace];
|
||||||
|
NSString* fileName = [NSString stringWithUTF8String:fileNameUTF8];
|
||||||
|
wasOpened = [workspace openFile:fileName withApplication:[applicationURL path]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return wasOpened == YES;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
155
editor/src/editor/layout/main.hpp
Normal file
|
|
@ -0,0 +1,155 @@
|
||||||
|
/* This file is generated by the layout maker tool. */
|
||||||
|
LogicalGroup* const view__0 = createLogicalGroup(CRect(0, 0, 800, 475), -1, "", kCenterText, 14);
|
||||||
|
mainView = view__0;
|
||||||
|
Background* const view__1 = createBackground(CRect(190, 110, 790, 390), -1, "", kCenterText, 14);
|
||||||
|
view__0->addView(view__1);
|
||||||
|
enterTheme(darkTheme);
|
||||||
|
LogicalGroup* const view__2 = createLogicalGroup(CRect(0, 0, 800, 110), -1, "", kCenterText, 14);
|
||||||
|
view__0->addView(view__2);
|
||||||
|
RoundedGroup* const view__3 = createRoundedGroup(CRect(5, 4, 180, 105), -1, "", kCenterText, 14);
|
||||||
|
view__2->addView(view__3);
|
||||||
|
SfizzMainButton* const view__4 = createSfizzMainButton(CRect(30, 5, 150, 65), kTagFirstChangePanel+kPanelGeneral, "", kCenterText, 14);
|
||||||
|
view__3->addView(view__4);
|
||||||
|
HomeButton* const view__5 = createHomeButton(CRect(44, 69, 69, 94), kTagFirstChangePanel+kPanelGeneral, "", kCenterText, 24);
|
||||||
|
view__3->addView(view__5);
|
||||||
|
CCButton* const view__6 = createCCButton(CRect(76, 69, 101, 94), kTagFirstChangePanel+kPanelControls, "", kCenterText, 24);
|
||||||
|
view__3->addView(view__6);
|
||||||
|
SettingsButton* const view__7 = createSettingsButton(CRect(107, 69, 132, 94), kTagFirstChangePanel+kPanelSettings, "", kCenterText, 24);
|
||||||
|
view__3->addView(view__7);
|
||||||
|
RoundedGroup* const view__8 = createRoundedGroup(CRect(185, 5, 565, 105), -1, "", kCenterText, 14);
|
||||||
|
view__2->addView(view__8);
|
||||||
|
HLine* const view__9 = createHLine(CRect(10, 36, 370, 41), -1, "", kCenterText, 14);
|
||||||
|
view__8->addView(view__9);
|
||||||
|
HLine* const view__10 = createHLine(CRect(10, 68, 370, 73), -1, "", kCenterText, 14);
|
||||||
|
view__8->addView(view__10);
|
||||||
|
ClickableLabel* const view__11 = createClickableLabel(CRect(10, 6, 260, 37), kTagLoadSfzFile, "DefaultInstrument.sfz", kLeftText, 20);
|
||||||
|
sfzFileLabel_ = view__11;
|
||||||
|
view__8->addView(view__11);
|
||||||
|
Label* const view__12 = createLabel(CRect(10, 39, 260, 69), -1, "Key switch:", kLeftText, 20);
|
||||||
|
view__8->addView(view__12);
|
||||||
|
Label* const view__13 = createLabel(CRect(10, 71, 70, 96), -1, "Voices:", kRightText, 12);
|
||||||
|
view__8->addView(view__13);
|
||||||
|
PreviousFileButton* const view__14 = createPreviousFileButton(CRect(295, 9, 320, 34), kTagPreviousSfzFile, "", kCenterText, 24);
|
||||||
|
view__8->addView(view__14);
|
||||||
|
NextFileButton* const view__15 = createNextFileButton(CRect(320, 9, 345, 34), kTagNextSfzFile, "", kCenterText, 24);
|
||||||
|
view__8->addView(view__15);
|
||||||
|
ChevronDropDown* const view__16 = createChevronDropDown(CRect(345, 9, 370, 34), kTagFileOperations, "", kCenterText, 24);
|
||||||
|
fileOperationsMenu_ = view__16;
|
||||||
|
view__8->addView(view__16);
|
||||||
|
Label* const view__17 = createLabel(CRect(75, 71, 125, 96), -1, "", kCenterText, 12);
|
||||||
|
infoVoicesLabel_ = view__17;
|
||||||
|
view__8->addView(view__17);
|
||||||
|
Label* const view__18 = createLabel(CRect(130, 71, 190, 96), -1, "Max:", kRightText, 12);
|
||||||
|
view__8->addView(view__18);
|
||||||
|
Label* const view__19 = createLabel(CRect(195, 71, 245, 96), -1, "", kCenterText, 12);
|
||||||
|
numVoicesLabel_ = view__19;
|
||||||
|
view__8->addView(view__19);
|
||||||
|
Label* const view__20 = createLabel(CRect(250, 71, 310, 96), -1, "Memory:", kRightText, 12);
|
||||||
|
view__8->addView(view__20);
|
||||||
|
Label* const view__21 = createLabel(CRect(315, 71, 365, 96), -1, "", kCenterText, 12);
|
||||||
|
memoryLabel_ = view__21;
|
||||||
|
view__8->addView(view__21);
|
||||||
|
RoundedGroup* const view__22 = createRoundedGroup(CRect(570, 5, 795, 105), -1, "", kCenterText, 14);
|
||||||
|
view__2->addView(view__22);
|
||||||
|
Knob48* const view__23 = createKnob48(CRect(45, 15, 93, 63), -1, "", kCenterText, 14);
|
||||||
|
view__22->addView(view__23);
|
||||||
|
view__23->setVisible(false);
|
||||||
|
ValueLabel* const view__24 = createValueLabel(CRect(40, 65, 100, 70), -1, "Center", kCenterText, 12);
|
||||||
|
view__22->addView(view__24);
|
||||||
|
view__24->setVisible(false);
|
||||||
|
StyledKnob* const view__25 = createStyledKnob(CRect(110, 15, 158, 63), kTagSetVolume, "", kCenterText, 14);
|
||||||
|
volumeSlider_ = view__25;
|
||||||
|
view__22->addView(view__25);
|
||||||
|
ValueLabel* const view__26 = createValueLabel(CRect(105, 65, 165, 87), -1, "0.0 dB", kCenterText, 12);
|
||||||
|
volumeLabel_ = view__26;
|
||||||
|
view__22->addView(view__26);
|
||||||
|
VMeter* const view__27 = createVMeter(CRect(175, 15, 210, 70), -1, "", kCenterText, 14);
|
||||||
|
view__22->addView(view__27);
|
||||||
|
enterTheme(defaultTheme);
|
||||||
|
LogicalGroup* const view__28 = createLogicalGroup(CRect(5, 110, 796, 395), -1, "", kCenterText, 14);
|
||||||
|
subPanels_[kPanelGeneral] = view__28;
|
||||||
|
view__0->addView(view__28);
|
||||||
|
RoundedGroup* const view__29 = createRoundedGroup(CRect(0, 0, 175, 280), -1, "", kCenterText, 14);
|
||||||
|
view__28->addView(view__29);
|
||||||
|
Label* const view__30 = createLabel(CRect(15, 10, 75, 35), -1, "Curves:", kLeftText, 14);
|
||||||
|
view__29->addView(view__30);
|
||||||
|
Label* const view__31 = createLabel(CRect(15, 35, 75, 60), -1, "Masters:", kLeftText, 14);
|
||||||
|
view__29->addView(view__31);
|
||||||
|
Label* const view__32 = createLabel(CRect(15, 60, 75, 85), -1, "Groups:", kLeftText, 14);
|
||||||
|
view__29->addView(view__32);
|
||||||
|
Label* const view__33 = createLabel(CRect(15, 85, 75, 110), -1, "Regions:", kLeftText, 14);
|
||||||
|
view__29->addView(view__33);
|
||||||
|
Label* const view__34 = createLabel(CRect(15, 110, 75, 135), -1, "Samples:", kLeftText, 14);
|
||||||
|
view__29->addView(view__34);
|
||||||
|
Label* const view__35 = createLabel(CRect(115, 10, 155, 35), -1, "0", kCenterText, 14);
|
||||||
|
infoCurvesLabel_ = view__35;
|
||||||
|
view__29->addView(view__35);
|
||||||
|
Label* const view__36 = createLabel(CRect(115, 35, 155, 60), -1, "0", kCenterText, 14);
|
||||||
|
infoMastersLabel_ = view__36;
|
||||||
|
view__29->addView(view__36);
|
||||||
|
Label* const view__37 = createLabel(CRect(115, 60, 155, 85), -1, "0", kCenterText, 14);
|
||||||
|
infoGroupsLabel_ = view__37;
|
||||||
|
view__29->addView(view__37);
|
||||||
|
Label* const view__38 = createLabel(CRect(115, 85, 155, 110), -1, "0", kCenterText, 14);
|
||||||
|
infoRegionsLabel_ = view__38;
|
||||||
|
view__29->addView(view__38);
|
||||||
|
Label* const view__39 = createLabel(CRect(115, 110, 155, 135), -1, "0", kCenterText, 14);
|
||||||
|
infoSamplesLabel_ = view__39;
|
||||||
|
view__29->addView(view__39);
|
||||||
|
LogicalGroup* const view__40 = createLogicalGroup(CRect(5, 110, 795, 395), -1, "", kCenterText, 14);
|
||||||
|
subPanels_[kPanelControls] = view__40;
|
||||||
|
view__0->addView(view__40);
|
||||||
|
view__40->setVisible(false);
|
||||||
|
RoundedGroup* const view__41 = createRoundedGroup(CRect(0, 0, 790, 285), -1, "", kCenterText, 14);
|
||||||
|
view__40->addView(view__41);
|
||||||
|
Label* const view__42 = createLabel(CRect(0, 0, 790, 285), -1, "Controls not available", kCenterText, 40);
|
||||||
|
view__41->addView(view__42);
|
||||||
|
LogicalGroup* const view__43 = createLogicalGroup(CRect(5, 109, 795, 395), -1, "", kCenterText, 14);
|
||||||
|
subPanels_[kPanelSettings] = view__43;
|
||||||
|
view__0->addView(view__43);
|
||||||
|
view__43->setVisible(false);
|
||||||
|
TitleGroup* const view__44 = createTitleGroup(CRect(255, 26, 535, 126), -1, "Engine", kCenterText, 12);
|
||||||
|
view__43->addView(view__44);
|
||||||
|
ValueMenu* const view__45 = createValueMenu(CRect(25, 60, 85, 85), kTagSetNumVoices, "", kCenterText, 12);
|
||||||
|
numVoicesSlider_ = view__45;
|
||||||
|
view__44->addView(view__45);
|
||||||
|
ValueLabel* const view__46 = createValueLabel(CRect(15, 20, 95, 45), -1, "Polyphony", kCenterText, 12);
|
||||||
|
view__44->addView(view__46);
|
||||||
|
ValueMenu* const view__47 = createValueMenu(CRect(110, 60, 170, 85), kTagSetOversampling, "", kCenterText, 12);
|
||||||
|
oversamplingSlider_ = view__47;
|
||||||
|
view__44->addView(view__47);
|
||||||
|
ValueLabel* const view__48 = createValueLabel(CRect(100, 20, 180, 45), -1, "Oversampling", kCenterText, 12);
|
||||||
|
view__44->addView(view__48);
|
||||||
|
ValueLabel* const view__49 = createValueLabel(CRect(185, 20, 265, 45), -1, "Preload size", kCenterText, 12);
|
||||||
|
view__44->addView(view__49);
|
||||||
|
ValueMenu* const view__50 = createValueMenu(CRect(195, 60, 255, 85), kTagSetPreloadSize, "", kCenterText, 12);
|
||||||
|
preloadSizeSlider_ = view__50;
|
||||||
|
view__44->addView(view__50);
|
||||||
|
TitleGroup* const view__51 = createTitleGroup(CRect(200, 161, 590, 261), -1, "Tuning", kCenterText, 12);
|
||||||
|
view__43->addView(view__51);
|
||||||
|
ValueLabel* const view__52 = createValueLabel(CRect(125, 20, 205, 45), -1, "Root key", kCenterText, 12);
|
||||||
|
view__51->addView(view__52);
|
||||||
|
ValueMenu* const view__53 = createValueMenu(CRect(220, 60, 280, 85), kTagSetTuningFrequency, "", kCenterText, 12);
|
||||||
|
tuningFrequencySlider_ = view__53;
|
||||||
|
view__51->addView(view__53);
|
||||||
|
ValueLabel* const view__54 = createValueLabel(CRect(210, 20, 290, 45), -1, "Frequency", kCenterText, 12);
|
||||||
|
view__51->addView(view__54);
|
||||||
|
StyledKnob* const view__55 = createStyledKnob(CRect(310, 45, 358, 93), kTagSetStretchedTuning, "", kCenterText, 14);
|
||||||
|
stretchedTuningSlider_ = view__55;
|
||||||
|
view__51->addView(view__55);
|
||||||
|
ValueLabel* const view__56 = createValueLabel(CRect(295, 20, 375, 45), -1, "Stretch", kCenterText, 12);
|
||||||
|
view__51->addView(view__56);
|
||||||
|
ValueLabel* const view__57 = createValueLabel(CRect(20, 20, 120, 45), -1, "Scala file", kCenterText, 12);
|
||||||
|
view__51->addView(view__57);
|
||||||
|
ValueButton* const view__58 = createValueButton(CRect(20, 60, 120, 85), kTagLoadScalaFile, "DefaultScale", kCenterText, 12);
|
||||||
|
scalaFileButton_ = view__58;
|
||||||
|
view__51->addView(view__58);
|
||||||
|
ValueMenu* const view__59 = createValueMenu(CRect(135, 60, 170, 85), kTagSetScalaRootKey, "", kCenterText, 12);
|
||||||
|
scalaRootKeySlider_ = view__59;
|
||||||
|
view__51->addView(view__59);
|
||||||
|
ValueMenu* const view__60 = createValueMenu(CRect(170, 60, 200, 85), kTagSetScalaRootKey, "", kCenterText, 12);
|
||||||
|
scalaRootOctaveSlider_ = view__60;
|
||||||
|
view__51->addView(view__60);
|
||||||
|
Piano* const view__61 = createPiano(CRect(5, 400, 795, 470), -1, "", kCenterText, 12);
|
||||||
|
piano_ = view__61;
|
||||||
|
view__0->addView(view__61);
|
||||||
9
editor/src/editor/utility/vstgui_after.h
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
14
editor/src/editor/utility/vstgui_before.h
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||||
|
#pragma GCC diagnostic ignored "-Wignored-qualifiers"
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated-copy"
|
||||||
|
#pragma GCC diagnostic ignored "-Wmultichar"
|
||||||
|
#pragma GCC diagnostic ignored "-Wextra"
|
||||||
|
#endif
|
||||||
23
editor/tools/layout-maker/LICENSE
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
Boost Software License - Version 1.0 - August 17th, 2003
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
2
editor/tools/layout-maker/README
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
This purpose of this tool is to accept UI designs make with Fluid, the FLTK
|
||||||
|
design editor, and convert these designs to music plugin interfaces.
|
||||||
42
editor/tools/layout-maker/sources/layout.h
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
#pragma once
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct LayoutImage {
|
||||||
|
std::string filepath;
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
int w = 0;
|
||||||
|
int h = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LayoutItem {
|
||||||
|
std::string id;
|
||||||
|
std::string classname;
|
||||||
|
std::string label;
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
int w = 0;
|
||||||
|
int h = 0;
|
||||||
|
std::string box;
|
||||||
|
std::string down_box;
|
||||||
|
int labelfont = 0;
|
||||||
|
int labelsize = 14;
|
||||||
|
std::string labeltype;
|
||||||
|
int textsize = 14;
|
||||||
|
int align = 0;
|
||||||
|
double value = 0;
|
||||||
|
double minimum = 0;
|
||||||
|
double maximum = 0;
|
||||||
|
double step = 0;
|
||||||
|
std::string type;
|
||||||
|
std::string callback;
|
||||||
|
LayoutImage image;
|
||||||
|
bool hidden = false;
|
||||||
|
std::string comment;
|
||||||
|
std::vector<LayoutItem> items;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Layout {
|
||||||
|
std::vector<LayoutItem> items;
|
||||||
|
};
|
||||||
136
editor/tools/layout-maker/sources/main.cpp
Normal file
|
|
@ -0,0 +1,136 @@
|
||||||
|
#include "layout.h"
|
||||||
|
#include "reader.h"
|
||||||
|
#include <absl/strings/ascii.h>
|
||||||
|
#include <absl/strings/string_view.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
///
|
||||||
|
typedef std::unordered_map<std::string, std::string> Metadata;
|
||||||
|
|
||||||
|
static Metadata metadata_from_comment(absl::string_view comment)
|
||||||
|
{
|
||||||
|
Metadata md;
|
||||||
|
|
||||||
|
while (!comment.empty()) {
|
||||||
|
absl::string_view line;
|
||||||
|
|
||||||
|
size_t pos = comment.find_first_of("\r\n");
|
||||||
|
if (pos != comment.npos) {
|
||||||
|
line = comment.substr(0, pos);
|
||||||
|
comment.remove_prefix(pos + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
line = comment;
|
||||||
|
comment = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
line = absl::StripAsciiWhitespace(line);
|
||||||
|
if (line.empty() || line[0] == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
std::string key, value;
|
||||||
|
pos = line.find_first_of('=');
|
||||||
|
if (pos != comment.npos) {
|
||||||
|
key = std::string(line.substr(0, pos));
|
||||||
|
value = std::string(line.substr(pos + 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
key = std::string(line);
|
||||||
|
|
||||||
|
md.emplace(std::move(key), std::move(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
return md;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
static void codegen_item(int& idCounter, int parentId, int parentX, int parentY, const LayoutItem& item, absl::string_view oldTheme)
|
||||||
|
{
|
||||||
|
const Metadata md = metadata_from_comment(item.comment);
|
||||||
|
|
||||||
|
absl::string_view tag = "-1";
|
||||||
|
absl::string_view newTheme;
|
||||||
|
|
||||||
|
Metadata::const_iterator it;
|
||||||
|
it = md.find("tag");
|
||||||
|
if (it != md.end())
|
||||||
|
tag = it->second;
|
||||||
|
it = md.find("theme");
|
||||||
|
if (it != md.end())
|
||||||
|
newTheme = it->second;
|
||||||
|
|
||||||
|
absl::string_view currentTheme = newTheme.empty() ? oldTheme : newTheme;
|
||||||
|
|
||||||
|
int id = idCounter++;
|
||||||
|
int myX = item.x;
|
||||||
|
int myY = item.y;
|
||||||
|
if (parentId == -1) {
|
||||||
|
myX = 0;
|
||||||
|
myY = 0;
|
||||||
|
}
|
||||||
|
int relX = myX - parentX;
|
||||||
|
int relY = myY - parentY;
|
||||||
|
|
||||||
|
//std::cout << "// Begin " << id << " " << item.classname << " {" << item.label << "}" << "\n";
|
||||||
|
|
||||||
|
if (!newTheme.empty())
|
||||||
|
std::cout << "enterTheme(" << newTheme << ");\n";
|
||||||
|
|
||||||
|
absl::string_view label;
|
||||||
|
if (!item.label.empty() && item.labeltype != "NO_LABEL")
|
||||||
|
label = item.label;
|
||||||
|
|
||||||
|
absl::string_view align = "kCenterText";
|
||||||
|
if (item.align & 4)
|
||||||
|
align = "kLeftText";
|
||||||
|
else if (item.align & 8)
|
||||||
|
align = "kRightText";
|
||||||
|
|
||||||
|
std::cout << item.classname << "* const view__" << id << " = create" << item.classname << "(CRect(" << relX << ", " << relY << ", " << (relX + item.w) << ", " << (relY + item.h) << "), " << tag << ", \"" << label << "\", " << align << ", " << item.labelsize << ");\n";
|
||||||
|
|
||||||
|
if (!item.id.empty())
|
||||||
|
std::cout << item.id << " = view__" << id << ";\n";
|
||||||
|
|
||||||
|
if (parentId != -1)
|
||||||
|
std::cout << "view__" << parentId << "->addView(view__" << id << ");\n";
|
||||||
|
|
||||||
|
if (item.hidden)
|
||||||
|
std::cout << "view__" << id << "->setVisible(false);\n";
|
||||||
|
|
||||||
|
for (const LayoutItem& subItem : item.items)
|
||||||
|
codegen_item(idCounter, id, myX, myY, subItem, currentTheme);
|
||||||
|
|
||||||
|
if (!newTheme.empty())
|
||||||
|
std::cout << "enterTheme(" << oldTheme << ");\n";
|
||||||
|
|
||||||
|
//std::cout << "// End " << id << " " << item.classname << " {" << item.label << "}" << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void codegen_layout(const LayoutItem& item)
|
||||||
|
{
|
||||||
|
int idCounter = 0;
|
||||||
|
codegen_item(idCounter, -1, 0, 0, item, "defaultTheme");
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if (argc != 2) {
|
||||||
|
std::cerr << "Please indicate a fluid design file.\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Layout layout = read_file_layout(argv[1]);
|
||||||
|
|
||||||
|
if (layout.items.size() != 1) {
|
||||||
|
std::cerr << "There must be exactly 1 top level component.";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "/* This file is generated by the layout maker tool. */\n";
|
||||||
|
|
||||||
|
codegen_layout(layout.items[0]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
298
editor/tools/layout-maker/sources/reader.cpp
Normal file
|
|
@ -0,0 +1,298 @@
|
||||||
|
#include "reader.h"
|
||||||
|
#include <absl/strings/string_view.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
typedef std::vector<std::string> TokenList;
|
||||||
|
static bool read_file_tokens(const char *filename, TokenList &tokens);
|
||||||
|
static Layout read_tokens_layout(TokenList::iterator &tok_it, TokenList::iterator tok_end);
|
||||||
|
|
||||||
|
Layout read_file_layout(const char *filename)
|
||||||
|
{
|
||||||
|
std::vector<std::string> tokens;
|
||||||
|
if (!read_file_tokens(filename, tokens))
|
||||||
|
throw std::runtime_error("Cannot read fluid design file.");
|
||||||
|
|
||||||
|
TokenList::iterator tok_it = tokens.begin();
|
||||||
|
TokenList::iterator tok_end = tokens.end();
|
||||||
|
return read_tokens_layout(tok_it, tok_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string consume_next_token(TokenList::iterator &tok_it, TokenList::iterator tok_end)
|
||||||
|
{
|
||||||
|
if (tok_it == tok_end)
|
||||||
|
throw file_format_error("Premature end of tokens");
|
||||||
|
return *tok_it++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool try_consume_next_token(const char *text, TokenList::iterator &tok_it, TokenList::iterator tok_end)
|
||||||
|
{
|
||||||
|
if (tok_it == tok_end)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (*tok_it != text)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
++tok_it;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ensure_next_token(const char *text, TokenList::iterator &tok_it, TokenList::iterator tok_end)
|
||||||
|
{
|
||||||
|
std::string tok = consume_next_token(tok_it, tok_end);
|
||||||
|
if (tok != text)
|
||||||
|
throw file_format_error("Unexpected token: " + tok);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string consume_enclosed_string(TokenList::iterator &tok_it, TokenList::iterator tok_end)
|
||||||
|
{
|
||||||
|
ensure_next_token("{", tok_it, tok_end);
|
||||||
|
unsigned depth = 1;
|
||||||
|
|
||||||
|
std::string text;
|
||||||
|
for (;;) {
|
||||||
|
std::string part = consume_next_token(tok_it, tok_end);
|
||||||
|
if (part == "}") {
|
||||||
|
if (--depth == 0)
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
else if (part == "{")
|
||||||
|
++depth;
|
||||||
|
if (!text.empty())
|
||||||
|
text.push_back(' ');
|
||||||
|
text.append(part);
|
||||||
|
}
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string consume_any_string(TokenList::iterator &tok_it, TokenList::iterator tok_end)
|
||||||
|
{
|
||||||
|
if (tok_it != tok_end && *tok_it == "{")
|
||||||
|
return consume_enclosed_string(tok_it, tok_end);
|
||||||
|
else
|
||||||
|
return consume_next_token(tok_it, tok_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int consume_int_token(TokenList::iterator &tok_it, TokenList::iterator tok_end)
|
||||||
|
{
|
||||||
|
std::string text = consume_next_token(tok_it, tok_end);
|
||||||
|
return std::stoi(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int consume_real_token(TokenList::iterator &tok_it, TokenList::iterator tok_end)
|
||||||
|
{
|
||||||
|
std::string text = consume_next_token(tok_it, tok_end);
|
||||||
|
return std::stod(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void consume_layout_item_properties(LayoutItem &item, TokenList::iterator &tok_it, TokenList::iterator tok_end)
|
||||||
|
{
|
||||||
|
ensure_next_token("{", tok_it, tok_end);
|
||||||
|
for (bool have = true; have;) {
|
||||||
|
if (try_consume_next_token("open", tok_it, tok_end))
|
||||||
|
; // skip
|
||||||
|
else if (try_consume_next_token("selected", tok_it, tok_end))
|
||||||
|
; // skip
|
||||||
|
else if (try_consume_next_token("label", tok_it, tok_end))
|
||||||
|
item.label = consume_any_string(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("xywh", tok_it, tok_end)) {
|
||||||
|
ensure_next_token("{", tok_it, tok_end);
|
||||||
|
item.x = consume_int_token(tok_it, tok_end);
|
||||||
|
item.y = consume_int_token(tok_it, tok_end);
|
||||||
|
item.w = consume_int_token(tok_it, tok_end);
|
||||||
|
item.h = consume_int_token(tok_it, tok_end);
|
||||||
|
ensure_next_token("}", tok_it, tok_end);
|
||||||
|
}
|
||||||
|
else if (try_consume_next_token("box", tok_it, tok_end))
|
||||||
|
item.box = consume_next_token(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("down_box", tok_it, tok_end))
|
||||||
|
item.down_box = consume_next_token(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("labelfont", tok_it, tok_end))
|
||||||
|
item.labelfont = consume_int_token(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("labelsize", tok_it, tok_end))
|
||||||
|
item.labelsize = consume_int_token(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("labeltype", tok_it, tok_end))
|
||||||
|
item.labeltype = consume_any_string(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("textsize", tok_it, tok_end))
|
||||||
|
item.textsize = consume_int_token(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("align", tok_it, tok_end))
|
||||||
|
item.align = consume_int_token(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("type", tok_it, tok_end))
|
||||||
|
item.type = consume_any_string(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("callback", tok_it, tok_end))
|
||||||
|
item.callback = consume_any_string(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("class", tok_it, tok_end))
|
||||||
|
item.classname = consume_any_string(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("value", tok_it, tok_end))
|
||||||
|
item.value = consume_real_token(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("minimum", tok_it, tok_end))
|
||||||
|
item.minimum = consume_real_token(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("maximum", tok_it, tok_end))
|
||||||
|
item.maximum = consume_real_token(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("step", tok_it, tok_end))
|
||||||
|
item.step = consume_real_token(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("image", tok_it, tok_end))
|
||||||
|
item.image.filepath = consume_any_string(tok_it, tok_end);
|
||||||
|
else if (try_consume_next_token("hide", tok_it, tok_end))
|
||||||
|
item.hidden = true;
|
||||||
|
else if (try_consume_next_token("visible", tok_it, tok_end))
|
||||||
|
/* skip */;
|
||||||
|
else if (try_consume_next_token("comment", tok_it, tok_end))
|
||||||
|
item.comment = consume_any_string(tok_it, tok_end);
|
||||||
|
else
|
||||||
|
have = false;
|
||||||
|
}
|
||||||
|
ensure_next_token("}", tok_it, tok_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LayoutItem consume_layout_item(const std::string &classname, TokenList::iterator &tok_it, TokenList::iterator tok_end, bool anonymous = false)
|
||||||
|
{
|
||||||
|
LayoutItem item;
|
||||||
|
item.classname = classname;
|
||||||
|
if (!anonymous)
|
||||||
|
item.id = consume_any_string(tok_it, tok_end);
|
||||||
|
consume_layout_item_properties(item, tok_it, tok_end);
|
||||||
|
if (tok_it != tok_end && *tok_it == "{") {
|
||||||
|
consume_next_token(tok_it, tok_end);
|
||||||
|
for (std::string text; (text = consume_next_token(tok_it, tok_end)) != "}";) {
|
||||||
|
if (text == "decl") {
|
||||||
|
consume_any_string(tok_it, tok_end);
|
||||||
|
consume_any_string(tok_it, tok_end);
|
||||||
|
}
|
||||||
|
else if (text == "Function") {
|
||||||
|
consume_any_string(tok_it, tok_end);
|
||||||
|
consume_any_string(tok_it, tok_end);
|
||||||
|
consume_any_string(tok_it, tok_end);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
item.items.push_back(consume_layout_item(text, tok_it, tok_end));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Layout read_tokens_layout(TokenList::iterator &tok_it, TokenList::iterator tok_end)
|
||||||
|
{
|
||||||
|
Layout layout;
|
||||||
|
|
||||||
|
std::string version_name;
|
||||||
|
std::string header_name;
|
||||||
|
std::string code_name;
|
||||||
|
|
||||||
|
while (tok_it != tok_end) {
|
||||||
|
std::string key = consume_next_token(tok_it, tok_end);
|
||||||
|
|
||||||
|
if (key == "version")
|
||||||
|
version_name = consume_next_token(tok_it, tok_end);
|
||||||
|
else if (key == "header_name") {
|
||||||
|
ensure_next_token("{", tok_it, tok_end);
|
||||||
|
header_name = consume_next_token(tok_it, tok_end);
|
||||||
|
ensure_next_token("}", tok_it, tok_end);
|
||||||
|
}
|
||||||
|
else if (key == "code_name") {
|
||||||
|
ensure_next_token("{", tok_it, tok_end);
|
||||||
|
code_name = consume_next_token(tok_it, tok_end);
|
||||||
|
ensure_next_token("}", tok_it, tok_end);
|
||||||
|
}
|
||||||
|
else if (key == "decl") {
|
||||||
|
consume_any_string(tok_it, tok_end);
|
||||||
|
consume_any_string(tok_it, tok_end);
|
||||||
|
}
|
||||||
|
else if (key == "widget_class") {
|
||||||
|
key = consume_next_token(tok_it, tok_end);
|
||||||
|
layout.items.push_back(consume_layout_item(key, tok_it, tok_end, true));
|
||||||
|
layout.items.back().id = key;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
layout.items.push_back(consume_layout_item(key, tok_it, tok_end));
|
||||||
|
}
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
class tokenizer {
|
||||||
|
public:
|
||||||
|
tokenizer(
|
||||||
|
absl::string_view text,
|
||||||
|
absl::string_view dropped_delims,
|
||||||
|
absl::string_view kept_delims);
|
||||||
|
|
||||||
|
absl::string_view next();
|
||||||
|
|
||||||
|
private:
|
||||||
|
absl::string_view text_;
|
||||||
|
absl::string_view dropped_delims_;
|
||||||
|
absl::string_view kept_delims_;
|
||||||
|
};
|
||||||
|
|
||||||
|
tokenizer::tokenizer(
|
||||||
|
absl::string_view text,
|
||||||
|
absl::string_view dropped_delims,
|
||||||
|
absl::string_view kept_delims)
|
||||||
|
: text_(text), dropped_delims_(dropped_delims), kept_delims_(kept_delims)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::string_view tokenizer::next()
|
||||||
|
{
|
||||||
|
auto is_dropped = [this](char c) -> bool {
|
||||||
|
return dropped_delims_.find(c) != dropped_delims_.npos;
|
||||||
|
};
|
||||||
|
auto is_kept = [this](char c) -> bool {
|
||||||
|
return kept_delims_.find(c) != kept_delims_.npos;
|
||||||
|
};
|
||||||
|
auto is_delim = [this](char c) -> bool {
|
||||||
|
return dropped_delims_.find(c) != dropped_delims_.npos ||
|
||||||
|
kept_delims_.find(c) != kept_delims_.npos;
|
||||||
|
};
|
||||||
|
|
||||||
|
absl::string_view text = text_;
|
||||||
|
|
||||||
|
while (!text.empty() && is_dropped(text[0]))
|
||||||
|
text.remove_prefix(1);
|
||||||
|
|
||||||
|
if (text.empty())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
size_t pos;
|
||||||
|
{
|
||||||
|
auto it = std::find_if(text.begin(), text.end(), is_delim);
|
||||||
|
if (it == text.end())
|
||||||
|
pos = text.size();
|
||||||
|
else {
|
||||||
|
pos = std::distance(text.begin(), it);
|
||||||
|
pos += is_kept(text[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::string_view token = text.substr(0, pos);
|
||||||
|
text_ = text.substr(pos);
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
static bool read_file_tokens(const char *filename, TokenList &tokens)
|
||||||
|
{
|
||||||
|
std::ifstream stream(filename);
|
||||||
|
std::string line;
|
||||||
|
|
||||||
|
std::string text;
|
||||||
|
while (std::getline(stream, line)) {
|
||||||
|
if (!line.empty() && line[0] != '#') {
|
||||||
|
text.append(line);
|
||||||
|
text.push_back('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stream.bad())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tokenizer tok(text, " \t\r\n", "{}");
|
||||||
|
absl::string_view token;
|
||||||
|
while (!(token = tok.next()).empty())
|
||||||
|
tokens.emplace_back(token);
|
||||||
|
|
||||||
|
return !stream.bad();
|
||||||
|
}
|
||||||
13
editor/tools/layout-maker/sources/reader.h
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
#include "layout.h"
|
||||||
|
#include <string>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
Layout read_file_layout(const char *filename);
|
||||||
|
|
||||||
|
///
|
||||||
|
struct file_format_error : public std::runtime_error {
|
||||||
|
public:
|
||||||
|
explicit file_format_error(const std::string &reason = "Format error")
|
||||||
|
: runtime_error(reason) {}
|
||||||
|
};
|
||||||
23
external/jsl/LICENSE.md
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Boost Software License - Version 1.0 - August 17th, 2003
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
73
external/jsl/include/jsl/allocator
vendored
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
// -*- C++ -*-
|
||||||
|
#pragma once
|
||||||
|
#include <limits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace jsl {
|
||||||
|
|
||||||
|
template <class T, class Traits>
|
||||||
|
struct ordinary_allocator {
|
||||||
|
typedef T value_type;
|
||||||
|
typedef T *pointer;
|
||||||
|
typedef const T *const_pointer;
|
||||||
|
typedef T &reference;
|
||||||
|
typedef const T &const_reference;
|
||||||
|
typedef std::size_t size_type;
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
typedef std::true_type propagate_on_container_move_assignment;
|
||||||
|
template <class U> struct rebind { typedef ordinary_allocator<U, Traits> other; };
|
||||||
|
typedef std::true_type is_always_equal;
|
||||||
|
|
||||||
|
ordinary_allocator() noexcept {}
|
||||||
|
ordinary_allocator(const ordinary_allocator &) noexcept {}
|
||||||
|
template <class U> ordinary_allocator(const ordinary_allocator<U, Traits>&) noexcept {}
|
||||||
|
|
||||||
|
T *address(T &x) const noexcept;
|
||||||
|
const T *address(const T &x) const noexcept;
|
||||||
|
|
||||||
|
T *allocate(std::size_t n, const void * = nullptr);
|
||||||
|
void deallocate(T *p, std::size_t n) noexcept;
|
||||||
|
std::size_t max_size() const noexcept;
|
||||||
|
|
||||||
|
template <class U, class... Args> void construct(U *p, Args &&...args);
|
||||||
|
template <class U> void destroy(U *p);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class Traits>
|
||||||
|
inline bool operator==(const ordinary_allocator<T, Traits> &, const ordinary_allocator<T, Traits> &) noexcept
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class Traits>
|
||||||
|
inline bool operator!=(const ordinary_allocator<T, Traits> &, const ordinary_allocator<T, Traits> &) noexcept
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct stdc_allocator_traits {
|
||||||
|
static void *allocate(std::size_t n);
|
||||||
|
static void deallocate(void *p, std::size_t = 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
using stdc_allocator = ordinary_allocator<T, stdc_allocator_traits>;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <std::size_t Al>
|
||||||
|
struct aligned_allocator_traits {
|
||||||
|
static void *allocate(std::size_t n);
|
||||||
|
static void deallocate(void *p, std::size_t = 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, std::size_t Al>
|
||||||
|
using aligned_allocator = ordinary_allocator<T, aligned_allocator_traits<Al>>;
|
||||||
|
|
||||||
|
} // namespace jsl
|
||||||
|
|
||||||
|
#include "bits/allocator/ordinary_allocator.tcc"
|
||||||
|
#include "bits/allocator/stdc_allocator.tcc"
|
||||||
|
#include "bits/allocator/aligned_allocator.tcc"
|
||||||
41
external/jsl/include/jsl/bits/allocator/aligned_allocator.tcc
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
#include "../../allocator"
|
||||||
|
#include <new>
|
||||||
|
#if defined(_WIN32)
|
||||||
|
# include <malloc.h>
|
||||||
|
#else
|
||||||
|
# include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace jsl {
|
||||||
|
|
||||||
|
template <std::size_t Al>
|
||||||
|
void *aligned_allocator_traits<Al>::allocate(std::size_t n)
|
||||||
|
{
|
||||||
|
static_assert(Al % sizeof(void *) == 0,
|
||||||
|
"alignment must be a multiple of the pointer size");
|
||||||
|
static_assert((Al & (~Al + 1)) == Al,
|
||||||
|
"alignment must be a power of two");
|
||||||
|
#if defined(_WIN32)
|
||||||
|
void *p = ::_aligned_malloc(n, Al);
|
||||||
|
if (!p)
|
||||||
|
throw std::bad_alloc();
|
||||||
|
return p;
|
||||||
|
#else
|
||||||
|
void *p;
|
||||||
|
if (::posix_memalign(&p, Al, n) != 0)
|
||||||
|
throw std::bad_alloc();
|
||||||
|
return p;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t Al>
|
||||||
|
void aligned_allocator_traits<Al>::deallocate(void *p, std::size_t)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32)
|
||||||
|
::_aligned_free(p);
|
||||||
|
#else
|
||||||
|
::free(p);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace jsl
|
||||||
53
external/jsl/include/jsl/bits/allocator/ordinary_allocator.tcc
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include "../../allocator"
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
namespace jsl {
|
||||||
|
|
||||||
|
template <class T, class Traits>
|
||||||
|
inline T *ordinary_allocator<T, Traits>::address(T &x) const noexcept
|
||||||
|
{
|
||||||
|
return &x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class Traits>
|
||||||
|
inline const T *ordinary_allocator<T, Traits>::address(const T &x) const noexcept
|
||||||
|
{
|
||||||
|
return &x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class Traits>
|
||||||
|
T *ordinary_allocator<T, Traits>::allocate(std::size_t n, const void *)
|
||||||
|
{
|
||||||
|
T *ptr = (T *)Traits::allocate(n * sizeof(T));
|
||||||
|
if (!ptr)
|
||||||
|
throw std::bad_alloc();
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class Traits>
|
||||||
|
void ordinary_allocator<T, Traits>::deallocate(T *p, std::size_t n) noexcept
|
||||||
|
{
|
||||||
|
Traits::deallocate(p, n * sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class Traits>
|
||||||
|
std::size_t ordinary_allocator<T, Traits>::max_size() const noexcept
|
||||||
|
{
|
||||||
|
return std::numeric_limits<std::size_t>::max() / sizeof(T);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class Traits>
|
||||||
|
template <class U, class... Args>
|
||||||
|
void ordinary_allocator<T, Traits>::construct(U *p, Args &&...args)
|
||||||
|
{
|
||||||
|
::new((void *)p) U(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class Traits>
|
||||||
|
template <class U>
|
||||||
|
void ordinary_allocator<T, Traits>::destroy(U *p)
|
||||||
|
{
|
||||||
|
p->~U();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace jsl
|
||||||
16
external/jsl/include/jsl/bits/allocator/stdc_allocator.tcc
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
#include "../../allocator"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
namespace jsl {
|
||||||
|
|
||||||
|
inline void *stdc_allocator_traits::allocate(std::size_t n)
|
||||||
|
{
|
||||||
|
return ::malloc(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void stdc_allocator_traits::deallocate(void *p, std::size_t)
|
||||||
|
{
|
||||||
|
::free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace jsl
|
||||||
|
|
@ -11,6 +11,10 @@ set (LV2PLUGIN_TTL_SRC_FILES
|
||||||
manifest.ttl.in
|
manifest.ttl.in
|
||||||
${PROJECT_NAME}.ttl.in
|
${PROJECT_NAME}.ttl.in
|
||||||
)
|
)
|
||||||
|
if (SFIZZ_LV2_UI)
|
||||||
|
list(APPEND LV2PLUGIN_TTL_SRC_FILES
|
||||||
|
${PROJECT_NAME}_ui.ttl.in)
|
||||||
|
endif()
|
||||||
source_group("Turtle Files" FILES
|
source_group("Turtle Files" FILES
|
||||||
${LV2PLUGIN_TTL_SRC_FILES}
|
${LV2PLUGIN_TTL_SRC_FILES}
|
||||||
)
|
)
|
||||||
|
|
@ -19,33 +23,63 @@ add_library (${LV2PLUGIN_PRJ_NAME} MODULE
|
||||||
atomic_compat.h
|
atomic_compat.h
|
||||||
${LV2PLUGIN_TTL_SRC_FILES})
|
${LV2PLUGIN_TTL_SRC_FILES})
|
||||||
target_link_libraries (${LV2PLUGIN_PRJ_NAME} ${PROJECT_NAME}::${PROJECT_NAME})
|
target_link_libraries (${LV2PLUGIN_PRJ_NAME} ${PROJECT_NAME}::${PROJECT_NAME})
|
||||||
|
|
||||||
|
if (SFIZZ_LV2_UI)
|
||||||
|
add_library (${LV2PLUGIN_PRJ_NAME}_ui MODULE
|
||||||
|
${PROJECT_NAME}_ui.cpp
|
||||||
|
vstgui_helpers.h
|
||||||
|
vstgui_helpers.cpp)
|
||||||
|
target_link_libraries (${LV2PLUGIN_PRJ_NAME}_ui sfizz_editor sfizz-vstgui)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Explicitely strip all symbols on Linux but lv2_descriptor()
|
# Explicitely strip all symbols on Linux but lv2_descriptor()
|
||||||
# MacOS linker does not support this apparently https://bugs.webkit.org/show_bug.cgi?id=144555
|
# MacOS linker does not support this apparently https://bugs.webkit.org/show_bug.cgi?id=144555
|
||||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||||
file(COPY lv2.version DESTINATION ${CMAKE_BINARY_DIR}/lv2)
|
file(COPY lv2.version DESTINATION ${CMAKE_BINARY_DIR}/lv2)
|
||||||
target_link_libraries(${LV2PLUGIN_PRJ_NAME} "-Wl,--version-script=lv2.version")
|
target_link_libraries(${LV2PLUGIN_PRJ_NAME} "-Wl,--version-script=lv2.version")
|
||||||
# target_link_libraries(${LV2PLUGIN_PRJ_NAME} "-Wl,-u,lv2_descriptor")
|
# target_link_libraries(${LV2PLUGIN_PRJ_NAME} "-Wl,-u,lv2_descriptor")
|
||||||
|
if (SFIZZ_LV2_UI)
|
||||||
|
file(COPY lv2ui.version DESTINATION ${CMAKE_BINARY_DIR}/lv2)
|
||||||
|
target_link_libraries(${LV2PLUGIN_PRJ_NAME}_ui "-Wl,--version-script=lv2ui.version")
|
||||||
|
# target_link_libraries(${LV2PLUGIN_PRJ_NAME}_ui "-Wl,-u,lv2ui_descriptor")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
target_include_directories(${LV2PLUGIN_PRJ_NAME} PRIVATE . external/ardour)
|
target_include_directories(${LV2PLUGIN_PRJ_NAME} PRIVATE . external/ardour)
|
||||||
sfizz_enable_lto_if_needed (${LV2PLUGIN_PRJ_NAME})
|
sfizz_enable_lto_if_needed (${LV2PLUGIN_PRJ_NAME})
|
||||||
if (MINGW)
|
if (MINGW)
|
||||||
set_target_properties (${LV2PLUGIN_PRJ_NAME} PROPERTIES LINK_FLAGS "-static")
|
set_target_properties (${LV2PLUGIN_PRJ_NAME} PROPERTIES LINK_FLAGS "-static")
|
||||||
endif()
|
endif()
|
||||||
|
if (SFIZZ_LV2_UI)
|
||||||
|
target_include_directories(${LV2PLUGIN_PRJ_NAME}_ui PRIVATE . external/ardour)
|
||||||
|
sfizz_enable_lto_if_needed (${LV2PLUGIN_PRJ_NAME}_ui)
|
||||||
|
if (MINGW)
|
||||||
|
set_target_properties (${LV2PLUGIN_PRJ_NAME}_ui PROPERTIES LINK_FLAGS "-static")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# Remove the "lib" prefix, rename the target name and build it in the .lv build dir
|
# Remove the "lib" prefix, rename the target name and build it in the .lv build dir
|
||||||
# <build_dir>/lv2/<plugin_name>_lv2.<ext> to
|
# <build_dir>/lv2/<plugin_name>_lv2.<ext> to
|
||||||
# <build_dir>/lv2/<plugin_name>.lv2/<plugin_name>.<ext>
|
# <build_dir>/lv2/<plugin_name>.lv2/<plugin_name>.<ext>
|
||||||
set_target_properties (${LV2PLUGIN_PRJ_NAME} PROPERTIES PREFIX "")
|
set_target_properties (${LV2PLUGIN_PRJ_NAME} PROPERTIES PREFIX "")
|
||||||
set_target_properties (${LV2PLUGIN_PRJ_NAME} PROPERTIES OUTPUT_NAME "${PROJECT_NAME}")
|
set_target_properties (${LV2PLUGIN_PRJ_NAME} PROPERTIES OUTPUT_NAME "${PROJECT_NAME}")
|
||||||
set_target_properties (${LV2PLUGIN_PRJ_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
|
set_target_properties (${LV2PLUGIN_PRJ_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/Contents/Binary/$<0:>")
|
||||||
|
|
||||||
|
if (SFIZZ_LV2_UI)
|
||||||
|
set_target_properties (${LV2PLUGIN_PRJ_NAME}_ui PROPERTIES PREFIX "")
|
||||||
|
set_target_properties (${LV2PLUGIN_PRJ_NAME}_ui PROPERTIES OUTPUT_NAME "${PROJECT_NAME}_ui")
|
||||||
|
set_target_properties (${LV2PLUGIN_PRJ_NAME}_ui PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/Contents/Binary/$<0:>")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Generate *.ttl files from *.in sources,
|
# Generate *.ttl files from *.in sources,
|
||||||
# create the destination directory if it doesn't exists and copy needed files
|
# create the destination directory if it doesn't exists and copy needed files
|
||||||
file (MAKE_DIRECTORY ${PROJECT_BINARY_DIR})
|
file (MAKE_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||||
configure_file (manifest.ttl.in ${PROJECT_BINARY_DIR}/manifest.ttl)
|
configure_file (manifest.ttl.in ${PROJECT_BINARY_DIR}/manifest.ttl)
|
||||||
configure_file (${PROJECT_NAME}.ttl.in ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.ttl)
|
configure_file (${PROJECT_NAME}.ttl.in ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.ttl)
|
||||||
|
if (SFIZZ_LV2_UI)
|
||||||
|
configure_file (${PROJECT_NAME}_ui.ttl.in ${PROJECT_BINARY_DIR}/${PROJECT_NAME}_ui.ttl)
|
||||||
|
endif()
|
||||||
configure_file (LICENSE.md.in ${PROJECT_BINARY_DIR}/LICENSE.md)
|
configure_file (LICENSE.md.in ${PROJECT_BINARY_DIR}/LICENSE.md)
|
||||||
if (SFIZZ_USE_VCPKG OR SFIZZ_STATIC_LIBSNDFILE OR CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
if (SFIZZ_USE_VCPKG OR SFIZZ_STATIC_DEPENDENCIES OR CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||||
file(COPY "lgpl-3.0.txt" DESTINATION ${PROJECT_BINARY_DIR})
|
file(COPY "lgpl-3.0.txt" DESTINATION ${PROJECT_BINARY_DIR})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
@ -54,12 +88,21 @@ set(LV2_RESOURCES
|
||||||
DefaultInstrument.sfz
|
DefaultInstrument.sfz
|
||||||
DefaultScale.scl)
|
DefaultScale.scl)
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND "${CMAKE_COMMAND}" -E make_directory "${PROJECT_BINARY_DIR}/Resources")
|
COMMAND "${CMAKE_COMMAND}" -E make_directory "${PROJECT_BINARY_DIR}/Contents/Resources")
|
||||||
foreach(res ${LV2_RESOURCES})
|
foreach(res ${LV2_RESOURCES})
|
||||||
file (COPY "${CMAKE_CURRENT_SOURCE_DIR}/resources/${res}"
|
file (COPY "${CMAKE_CURRENT_SOURCE_DIR}/resources/${res}"
|
||||||
DESTINATION "${PROJECT_BINARY_DIR}/Resources")
|
DESTINATION "${PROJECT_BINARY_DIR}/Contents/Resources")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
# Copy editor resources
|
||||||
|
if (SFIZZ_LV2_UI)
|
||||||
|
execute_process (
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E make_directory "${PROJECT_BINARY_DIR}/Contents/Resources")
|
||||||
|
copy_editor_resources(
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/../editor/resources"
|
||||||
|
"${PROJECT_BINARY_DIR}/Contents/Resources")
|
||||||
|
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}
|
||||||
|
|
|
||||||
|
|
@ -122,13 +122,13 @@ lv2_atom_sequence_next(const LV2_Atom_Event* i)
|
||||||
@endcode
|
@endcode
|
||||||
*/
|
*/
|
||||||
#define LV2_ATOM_SEQUENCE_FOREACH(seq, iter) \
|
#define LV2_ATOM_SEQUENCE_FOREACH(seq, iter) \
|
||||||
for (LV2_Atom_Event* (iter) = lv2_atom_sequence_begin(&(seq)->body); \
|
for (LV2_Atom_Event* iter = lv2_atom_sequence_begin(&(seq)->body); \
|
||||||
!lv2_atom_sequence_is_end(&(seq)->body, (seq)->atom.size, (iter)); \
|
!lv2_atom_sequence_is_end(&(seq)->body, (seq)->atom.size, (iter)); \
|
||||||
(iter) = lv2_atom_sequence_next(iter))
|
(iter) = lv2_atom_sequence_next(iter))
|
||||||
|
|
||||||
/** Like LV2_ATOM_SEQUENCE_FOREACH but for a headerless sequence body. */
|
/** Like LV2_ATOM_SEQUENCE_FOREACH but for a headerless sequence body. */
|
||||||
#define LV2_ATOM_SEQUENCE_BODY_FOREACH(body, size, iter) \
|
#define LV2_ATOM_SEQUENCE_BODY_FOREACH(body, size, iter) \
|
||||||
for (LV2_Atom_Event* (iter) = lv2_atom_sequence_begin(body); \
|
for (LV2_Atom_Event* iter = lv2_atom_sequence_begin(body); \
|
||||||
!lv2_atom_sequence_is_end(body, size, (iter)); \
|
!lv2_atom_sequence_is_end(body, size, (iter)); \
|
||||||
(iter) = lv2_atom_sequence_next(iter))
|
(iter) = lv2_atom_sequence_next(iter))
|
||||||
|
|
||||||
|
|
@ -219,13 +219,13 @@ lv2_atom_tuple_next(const LV2_Atom* i)
|
||||||
@endcode
|
@endcode
|
||||||
*/
|
*/
|
||||||
#define LV2_ATOM_TUPLE_FOREACH(tuple, iter) \
|
#define LV2_ATOM_TUPLE_FOREACH(tuple, iter) \
|
||||||
for (LV2_Atom* (iter) = lv2_atom_tuple_begin(tuple); \
|
for (LV2_Atom* iter = lv2_atom_tuple_begin(tuple); \
|
||||||
!lv2_atom_tuple_is_end(LV2_ATOM_BODY(tuple), (tuple)->atom.size, (iter)); \
|
!lv2_atom_tuple_is_end(LV2_ATOM_BODY(tuple), (tuple)->atom.size, (iter)); \
|
||||||
(iter) = lv2_atom_tuple_next(iter))
|
(iter) = lv2_atom_tuple_next(iter))
|
||||||
|
|
||||||
/** Like LV2_ATOM_TUPLE_FOREACH but for a headerless tuple body. */
|
/** Like LV2_ATOM_TUPLE_FOREACH but for a headerless tuple body. */
|
||||||
#define LV2_ATOM_TUPLE_BODY_FOREACH(body, size, iter) \
|
#define LV2_ATOM_TUPLE_BODY_FOREACH(body, size, iter) \
|
||||||
for (LV2_Atom* (iter) = (LV2_Atom*)(body); \
|
for (LV2_Atom* iter = (LV2_Atom*)(body); \
|
||||||
!lv2_atom_tuple_is_end(body, size, (iter)); \
|
!lv2_atom_tuple_is_end(body, size, (iter)); \
|
||||||
(iter) = lv2_atom_tuple_next(iter))
|
(iter) = lv2_atom_tuple_next(iter))
|
||||||
|
|
||||||
|
|
@ -275,13 +275,13 @@ lv2_atom_object_next(const LV2_Atom_Property_Body* i)
|
||||||
@endcode
|
@endcode
|
||||||
*/
|
*/
|
||||||
#define LV2_ATOM_OBJECT_FOREACH(obj, iter) \
|
#define LV2_ATOM_OBJECT_FOREACH(obj, iter) \
|
||||||
for (LV2_Atom_Property_Body* (iter) = lv2_atom_object_begin(&(obj)->body); \
|
for (LV2_Atom_Property_Body* iter = lv2_atom_object_begin(&(obj)->body); \
|
||||||
!lv2_atom_object_is_end(&(obj)->body, (obj)->atom.size, (iter)); \
|
!lv2_atom_object_is_end(&(obj)->body, (obj)->atom.size, (iter)); \
|
||||||
(iter) = lv2_atom_object_next(iter))
|
(iter) = lv2_atom_object_next(iter))
|
||||||
|
|
||||||
/** Like LV2_ATOM_OBJECT_FOREACH but for a headerless object body. */
|
/** Like LV2_ATOM_OBJECT_FOREACH but for a headerless object body. */
|
||||||
#define LV2_ATOM_OBJECT_BODY_FOREACH(body, size, iter) \
|
#define LV2_ATOM_OBJECT_BODY_FOREACH(body, size, iter) \
|
||||||
for (LV2_Atom_Property_Body* (iter) = lv2_atom_object_begin(body); \
|
for (LV2_Atom_Property_Body* iter = lv2_atom_object_begin(body); \
|
||||||
!lv2_atom_object_is_end(body, size, (iter)); \
|
!lv2_atom_object_is_end(body, size, (iter)); \
|
||||||
(iter) = lv2_atom_object_next(iter))
|
(iter) = lv2_atom_object_next(iter))
|
||||||
|
|
||||||
|
|
|
||||||
4
lv2/lv2ui.version
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
LV2UIABI_1.0 {
|
||||||
|
global: *lv2ui_descriptor*;
|
||||||
|
local: *;
|
||||||
|
};
|
||||||
|
|
@ -1,7 +1,13 @@
|
||||||
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||||
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
|
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||||
|
|
||||||
<@LV2PLUGIN_URI@>
|
<@LV2PLUGIN_URI@>
|
||||||
a lv2:Plugin ;
|
a lv2:Plugin ;
|
||||||
lv2:binary <@PROJECT_NAME@@CMAKE_SHARED_MODULE_SUFFIX@> ;
|
lv2:binary <Contents/Binary/@PROJECT_NAME@@CMAKE_SHARED_MODULE_SUFFIX@> ;
|
||||||
rdfs:seeAlso <@PROJECT_NAME@.ttl> .
|
rdfs:seeAlso <@PROJECT_NAME@.ttl> .
|
||||||
|
|
||||||
|
@LV2PLUGIN_IF_ENABLE_UI@<@LV2PLUGIN_URI@#ui>
|
||||||
|
@LV2PLUGIN_IF_ENABLE_UI@ a ui:@LV2_UI_TYPE@ ;
|
||||||
|
@LV2PLUGIN_IF_ENABLE_UI@ ui:binary <Contents/Binary/@PROJECT_NAME@_ui@CMAKE_SHARED_MODULE_SUFFIX@> ;
|
||||||
|
@LV2PLUGIN_IF_ENABLE_UI@ rdfs:seeAlso <@PROJECT_NAME@_ui.ttl> .
|
||||||
|
|
|
||||||
232
lv2/sfizz.c
|
|
@ -32,6 +32,9 @@
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "sfizz_lv2.h"
|
||||||
|
|
||||||
|
#include <lv2/atom/atom.h>
|
||||||
#include <lv2/atom/forge.h>
|
#include <lv2/atom/forge.h>
|
||||||
#include <lv2/atom/util.h>
|
#include <lv2/atom/util.h>
|
||||||
#include <lv2/buf-size/buf-size.h>
|
#include <lv2/buf-size/buf-size.h>
|
||||||
|
|
@ -58,23 +61,11 @@
|
||||||
|
|
||||||
#include "atomic_compat.h"
|
#include "atomic_compat.h"
|
||||||
|
|
||||||
#define SFIZZ_URI "http://sfztools.github.io/sfizz"
|
|
||||||
#define SFIZZ_PREFIX SFIZZ_URI "#"
|
|
||||||
#define SFIZZ__sfzFile "http://sfztools.github.io/sfizz:sfzfile"
|
|
||||||
#define SFIZZ__tuningfile "http://sfztools.github.io/sfizz:tuningfile"
|
|
||||||
#define SFIZZ__numVoices "http://sfztools.github.io/sfizz:numvoices"
|
|
||||||
#define SFIZZ__preloadSize "http://sfztools.github.io/sfizz:preload_size"
|
|
||||||
#define SFIZZ__oversampling "http://sfztools.github.io/sfizz:oversampling"
|
|
||||||
// These ones are just for the worker
|
|
||||||
#define SFIZZ__logStatus "http://sfztools.github.io/sfizz:log_status"
|
|
||||||
#define SFIZZ__checkModification "http://sfztools.github.io/sfizz:check_modification"
|
|
||||||
|
|
||||||
#define CHANNEL_MASK 0x0F
|
#define CHANNEL_MASK 0x0F
|
||||||
#define MIDI_CHANNEL(byte) (byte & CHANNEL_MASK)
|
#define MIDI_CHANNEL(byte) (byte & CHANNEL_MASK)
|
||||||
#define MIDI_STATUS(byte) (byte & ~CHANNEL_MASK)
|
#define MIDI_STATUS(byte) (byte & ~CHANNEL_MASK)
|
||||||
#define PITCH_BUILD_AND_CENTER(first_byte, last_byte) (int)(((unsigned int)last_byte << 7) + (unsigned int)first_byte) - 8192
|
#define PITCH_BUILD_AND_CENTER(first_byte, last_byte) (int)(((unsigned int)last_byte << 7) + (unsigned int)first_byte) - 8192
|
||||||
#define MAX_BLOCK_SIZE 8192
|
#define MAX_BLOCK_SIZE 8192
|
||||||
#define MAX_PATH_SIZE 1024
|
|
||||||
#define MAX_VOICES 256
|
#define MAX_VOICES 256
|
||||||
#define DEFAULT_VOICES 64
|
#define DEFAULT_VOICES 64
|
||||||
#define DEFAULT_OVERSAMPLING SFIZZ_OVERSAMPLING_X1
|
#define DEFAULT_OVERSAMPLING SFIZZ_OVERSAMPLING_X1
|
||||||
|
|
@ -82,8 +73,8 @@
|
||||||
#define LOG_SAMPLE_COUNT 48000
|
#define LOG_SAMPLE_COUNT 48000
|
||||||
#define UNUSED(x) (void)(x)
|
#define UNUSED(x) (void)(x)
|
||||||
|
|
||||||
#define DEFAULT_SCALA_FILE "Resources/DefaultScale.scl"
|
#define DEFAULT_SCALA_FILE "Contents/Resources/DefaultScale.scl"
|
||||||
#define DEFAULT_SFZ_FILE "Resources/DefaultInstrument.sfz"
|
#define DEFAULT_SFZ_FILE "Contents/Resources/DefaultInstrument.sfz"
|
||||||
// This assumes that the longest path is the default sfz file; if not, change it
|
// This assumes that the longest path is the default sfz file; if not, change it
|
||||||
#define MAX_BUNDLE_PATH_SIZE (MAX_PATH_SIZE - sizeof(DEFAULT_SFZ_FILE))
|
#define MAX_BUNDLE_PATH_SIZE (MAX_PATH_SIZE - sizeof(DEFAULT_SFZ_FILE))
|
||||||
|
|
||||||
|
|
@ -114,6 +105,12 @@ typedef struct
|
||||||
const float *scala_root_key_port;
|
const float *scala_root_key_port;
|
||||||
const float *tuning_frequency_port;
|
const float *tuning_frequency_port;
|
||||||
const float *stretch_tuning_port;
|
const float *stretch_tuning_port;
|
||||||
|
float *active_voices_port;
|
||||||
|
float *num_curves_port;
|
||||||
|
float *num_masters_port;
|
||||||
|
float *num_groups_port;
|
||||||
|
float *num_regions_port;
|
||||||
|
float *num_samples_port;
|
||||||
|
|
||||||
// Atom forge
|
// Atom forge
|
||||||
LV2_Atom_Forge forge; ///< Forge for writing atoms in run thread
|
LV2_Atom_Forge forge; ///< Forge for writing atoms in run thread
|
||||||
|
|
@ -129,8 +126,11 @@ typedef struct
|
||||||
LV2_URID nominal_block_length_uri;
|
LV2_URID nominal_block_length_uri;
|
||||||
LV2_URID sample_rate_uri;
|
LV2_URID sample_rate_uri;
|
||||||
LV2_URID atom_object_uri;
|
LV2_URID atom_object_uri;
|
||||||
|
LV2_URID atom_blank_uri;
|
||||||
LV2_URID atom_float_uri;
|
LV2_URID atom_float_uri;
|
||||||
|
LV2_URID atom_double_uri;
|
||||||
LV2_URID atom_int_uri;
|
LV2_URID atom_int_uri;
|
||||||
|
LV2_URID atom_long_uri;
|
||||||
LV2_URID atom_urid_uri;
|
LV2_URID atom_urid_uri;
|
||||||
LV2_URID atom_path_uri;
|
LV2_URID atom_path_uri;
|
||||||
LV2_URID patch_set_uri;
|
LV2_URID patch_set_uri;
|
||||||
|
|
@ -147,7 +147,14 @@ typedef struct
|
||||||
LV2_URID sfizz_oversampling_uri;
|
LV2_URID sfizz_oversampling_uri;
|
||||||
LV2_URID sfizz_log_status_uri;
|
LV2_URID sfizz_log_status_uri;
|
||||||
LV2_URID sfizz_check_modification_uri;
|
LV2_URID sfizz_check_modification_uri;
|
||||||
|
LV2_URID sfizz_active_voices_uri;
|
||||||
LV2_URID time_position_uri;
|
LV2_URID time_position_uri;
|
||||||
|
LV2_URID time_bar_uri;
|
||||||
|
LV2_URID time_bar_beat_uri;
|
||||||
|
LV2_URID time_beat_unit_uri;
|
||||||
|
LV2_URID time_beats_per_bar_uri;
|
||||||
|
LV2_URID time_beats_per_minute_uri;
|
||||||
|
LV2_URID time_speed_uri;
|
||||||
|
|
||||||
// Sfizz related data
|
// Sfizz related data
|
||||||
sfizz_synth_t *synth;
|
sfizz_synth_t *synth;
|
||||||
|
|
@ -164,24 +171,24 @@ typedef struct
|
||||||
float sample_rate;
|
float sample_rate;
|
||||||
atomic_int must_update_midnam;
|
atomic_int must_update_midnam;
|
||||||
|
|
||||||
|
// Timing data
|
||||||
|
int bar;
|
||||||
|
float bar_beat;
|
||||||
|
int beats_per_bar;
|
||||||
|
int beat_unit;
|
||||||
|
float bpm_tempo;
|
||||||
|
float speed;
|
||||||
|
|
||||||
// Paths
|
// Paths
|
||||||
char bundle_path[MAX_BUNDLE_PATH_SIZE];
|
char bundle_path[MAX_BUNDLE_PATH_SIZE];
|
||||||
} sfizz_plugin_t;
|
} sfizz_plugin_t;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
SFIZZ_CONTROL = 0,
|
SFIZZ_TIMEINFO_POSITION = 1 << 0,
|
||||||
SFIZZ_NOTIFY = 1,
|
SFIZZ_TIMEINFO_SIGNATURE = 1 << 1,
|
||||||
SFIZZ_LEFT = 2,
|
SFIZZ_TIMEINFO_TEMPO = 1 << 2,
|
||||||
SFIZZ_RIGHT = 3,
|
SFIZZ_TIMEINFO_SPEED = 1 << 3,
|
||||||
SFIZZ_VOLUME = 4,
|
|
||||||
SFIZZ_POLYPHONY = 5,
|
|
||||||
SFIZZ_OVERSAMPLING = 6,
|
|
||||||
SFIZZ_PRELOAD = 7,
|
|
||||||
SFIZZ_FREEWHEELING = 8,
|
|
||||||
SFIZZ_SCALA_ROOT_KEY = 9,
|
|
||||||
SFIZZ_TUNING_FREQUENCY = 10,
|
|
||||||
SFIZZ_STRETCH_TUNING = 11,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -207,10 +214,13 @@ sfizz_lv2_map_required_uris(sfizz_plugin_t *self)
|
||||||
self->nominal_block_length_uri = map->map(map->handle, LV2_BUF_SIZE__nominalBlockLength);
|
self->nominal_block_length_uri = map->map(map->handle, LV2_BUF_SIZE__nominalBlockLength);
|
||||||
self->sample_rate_uri = map->map(map->handle, LV2_PARAMETERS__sampleRate);
|
self->sample_rate_uri = map->map(map->handle, LV2_PARAMETERS__sampleRate);
|
||||||
self->atom_float_uri = map->map(map->handle, LV2_ATOM__Float);
|
self->atom_float_uri = map->map(map->handle, LV2_ATOM__Float);
|
||||||
|
self->atom_double_uri = map->map(map->handle, LV2_ATOM__Double);
|
||||||
self->atom_int_uri = map->map(map->handle, LV2_ATOM__Int);
|
self->atom_int_uri = map->map(map->handle, LV2_ATOM__Int);
|
||||||
|
self->atom_long_uri = map->map(map->handle, LV2_ATOM__Long);
|
||||||
self->atom_path_uri = map->map(map->handle, LV2_ATOM__Path);
|
self->atom_path_uri = map->map(map->handle, LV2_ATOM__Path);
|
||||||
self->atom_urid_uri = map->map(map->handle, LV2_ATOM__URID);
|
self->atom_urid_uri = map->map(map->handle, LV2_ATOM__URID);
|
||||||
self->atom_object_uri = map->map(map->handle, LV2_ATOM__Object);
|
self->atom_object_uri = map->map(map->handle, LV2_ATOM__Object);
|
||||||
|
self->atom_blank_uri = map->map(map->handle, LV2_ATOM__Blank);
|
||||||
self->patch_set_uri = map->map(map->handle, LV2_PATCH__Set);
|
self->patch_set_uri = map->map(map->handle, LV2_PATCH__Set);
|
||||||
self->patch_get_uri = map->map(map->handle, LV2_PATCH__Get);
|
self->patch_get_uri = map->map(map->handle, LV2_PATCH__Get);
|
||||||
self->patch_put_uri = map->map(map->handle, LV2_PATCH__Put);
|
self->patch_put_uri = map->map(map->handle, LV2_PATCH__Put);
|
||||||
|
|
@ -224,8 +234,71 @@ sfizz_lv2_map_required_uris(sfizz_plugin_t *self)
|
||||||
self->sfizz_preload_size_uri = map->map(map->handle, SFIZZ__preloadSize);
|
self->sfizz_preload_size_uri = map->map(map->handle, SFIZZ__preloadSize);
|
||||||
self->sfizz_oversampling_uri = map->map(map->handle, SFIZZ__oversampling);
|
self->sfizz_oversampling_uri = map->map(map->handle, SFIZZ__oversampling);
|
||||||
self->sfizz_log_status_uri = map->map(map->handle, SFIZZ__logStatus);
|
self->sfizz_log_status_uri = map->map(map->handle, SFIZZ__logStatus);
|
||||||
|
self->sfizz_log_status_uri = map->map(map->handle, SFIZZ__logStatus);
|
||||||
self->sfizz_check_modification_uri = map->map(map->handle, SFIZZ__checkModification);
|
self->sfizz_check_modification_uri = map->map(map->handle, SFIZZ__checkModification);
|
||||||
self->time_position_uri = map->map(map->handle, LV2_TIME__Position);
|
self->time_position_uri = map->map(map->handle, LV2_TIME__Position);
|
||||||
|
self->time_bar_uri = map->map(map->handle, LV2_TIME__bar);
|
||||||
|
self->time_bar_beat_uri = map->map(map->handle, LV2_TIME__barBeat);
|
||||||
|
self->time_beat_unit_uri = map->map(map->handle, LV2_TIME__beatUnit);
|
||||||
|
self->time_beats_per_bar_uri = map->map(map->handle, LV2_TIME__beatsPerBar);
|
||||||
|
self->time_beats_per_minute_uri = map->map(map->handle, LV2_TIME__beatsPerMinute);
|
||||||
|
self->time_speed_uri = map->map(map->handle, LV2_TIME__speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
sfizz_atom_extract_real(sfizz_plugin_t *self, const LV2_Atom *atom, double *real)
|
||||||
|
{
|
||||||
|
if (!atom)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const LV2_URID type = atom->type;
|
||||||
|
|
||||||
|
if (type == self->atom_int_uri && atom->size >= sizeof(int32_t)) {
|
||||||
|
*real = ((const LV2_Atom_Int *)atom)->body;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == self->atom_long_uri && atom->size >= sizeof(int64_t)) {
|
||||||
|
*real = ((const LV2_Atom_Long *)atom)->body;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == self->atom_float_uri && atom->size >= sizeof(float)) {
|
||||||
|
*real = ((const LV2_Atom_Float *)atom)->body;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == self->atom_double_uri && atom->size >= sizeof(double)) {
|
||||||
|
*real = ((const LV2_Atom_Double *)atom)->body;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
sfizz_atom_extract_integer(sfizz_plugin_t *self, const LV2_Atom *atom, int64_t *integer)
|
||||||
|
{
|
||||||
|
if (!atom)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const LV2_URID type = atom->type;
|
||||||
|
|
||||||
|
if (type == self->atom_int_uri && atom->size >= sizeof(int32_t)) {
|
||||||
|
*integer = ((const LV2_Atom_Int *)atom)->body;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == self->atom_long_uri && atom->size >= sizeof(int64_t)) {
|
||||||
|
*integer = ((const LV2_Atom_Long *)atom)->body;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == self->atom_float_uri && atom->size >= sizeof(float)) {
|
||||||
|
*integer = (int64_t)((const LV2_Atom_Float *)atom)->body;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == self->atom_double_uri && atom->size >= sizeof(double)) {
|
||||||
|
*integer = (int64_t)((const LV2_Atom_Double *)atom)->body;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -272,6 +345,24 @@ connect_port(LV2_Handle instance,
|
||||||
case SFIZZ_STRETCH_TUNING:
|
case SFIZZ_STRETCH_TUNING:
|
||||||
self->stretch_tuning_port = (const float *)data;
|
self->stretch_tuning_port = (const float *)data;
|
||||||
break;
|
break;
|
||||||
|
case SFIZZ_ACTIVE_VOICES:
|
||||||
|
self->active_voices_port = (float *)data;
|
||||||
|
break;
|
||||||
|
case SFIZZ_NUM_CURVES:
|
||||||
|
self->num_curves_port = (float *)data;
|
||||||
|
break;
|
||||||
|
case SFIZZ_NUM_MASTERS:
|
||||||
|
self->num_masters_port = (float *)data;
|
||||||
|
break;
|
||||||
|
case SFIZZ_NUM_GROUPS:
|
||||||
|
self->num_groups_port = (float *)data;
|
||||||
|
break;
|
||||||
|
case SFIZZ_NUM_REGIONS:
|
||||||
|
self->num_regions_port = (float *)data;
|
||||||
|
break;
|
||||||
|
case SFIZZ_NUM_SAMPLES:
|
||||||
|
self->num_samples_port = (float *)data;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -319,6 +410,19 @@ sfizz_lv2_get_default_scala_path(LV2_Handle instance, char *path, size_t size)
|
||||||
snprintf(path, size, "%s/%s", self->bundle_path, DEFAULT_SCALA_FILE);
|
snprintf(path, size, "%s/%s", self->bundle_path, DEFAULT_SCALA_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sfizz_lv2_update_timeinfo(sfizz_plugin_t *self, int delay, int updates)
|
||||||
|
{
|
||||||
|
if (updates & SFIZZ_TIMEINFO_POSITION)
|
||||||
|
sfizz_send_time_position(self->synth, delay, self->bar, self->bar_beat);
|
||||||
|
if (updates & SFIZZ_TIMEINFO_SIGNATURE)
|
||||||
|
sfizz_send_time_signature(self->synth, delay, self->beats_per_bar, self->beat_unit);
|
||||||
|
if (updates & SFIZZ_TIMEINFO_TEMPO)
|
||||||
|
sfizz_send_tempo(self->synth, delay, 60.0f / self->bpm_tempo);
|
||||||
|
if (updates & SFIZZ_TIMEINFO_SPEED)
|
||||||
|
sfizz_send_playback_state(self->synth, delay, self->speed > 0);
|
||||||
|
}
|
||||||
|
|
||||||
static LV2_Handle
|
static LV2_Handle
|
||||||
instantiate(const LV2_Descriptor *descriptor,
|
instantiate(const LV2_Descriptor *descriptor,
|
||||||
double rate,
|
double rate,
|
||||||
|
|
@ -354,6 +458,14 @@ instantiate(const LV2_Descriptor *descriptor,
|
||||||
self->check_modification = false;
|
self->check_modification = false;
|
||||||
self->sample_counter = 0;
|
self->sample_counter = 0;
|
||||||
|
|
||||||
|
// Initial timing
|
||||||
|
self->bar = 0;
|
||||||
|
self->bar_beat = 0;
|
||||||
|
self->beats_per_bar = 4;
|
||||||
|
self->beat_unit = 4;
|
||||||
|
self->bpm_tempo = 120;
|
||||||
|
self->speed = 1;
|
||||||
|
|
||||||
// Get the features from the host and populate the structure
|
// Get the features from the host and populate the structure
|
||||||
for (const LV2_Feature *const *f = features; *f; f++)
|
for (const LV2_Feature *const *f = features; *f; f++)
|
||||||
{
|
{
|
||||||
|
|
@ -465,6 +577,8 @@ instantiate(const LV2_Descriptor *descriptor,
|
||||||
sfizz_load_file(self->synth, self->sfz_file_path);
|
sfizz_load_file(self->synth, self->sfz_file_path);
|
||||||
sfizz_load_scala_file(self->synth, self->scala_file_path);
|
sfizz_load_scala_file(self->synth, self->scala_file_path);
|
||||||
|
|
||||||
|
sfizz_lv2_update_timeinfo(self, 0, ~0);
|
||||||
|
|
||||||
return (LV2_Handle)self;
|
return (LV2_Handle)self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -509,7 +623,6 @@ sfizz_lv2_send_file_path(sfizz_plugin_t *self, LV2_URID urid, const char *path)
|
||||||
lv2_atom_forge_pop(&self->forge, &frame);
|
lv2_atom_forge_pop(&self->forge, &frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sfizz_lv2_handle_atom_object(sfizz_plugin_t *self, const LV2_Atom_Object *obj)
|
sfizz_lv2_handle_atom_object(sfizz_plugin_t *self, const LV2_Atom_Object *obj)
|
||||||
{
|
{
|
||||||
|
|
@ -745,8 +858,10 @@ run(LV2_Handle instance, uint32_t sample_count)
|
||||||
|
|
||||||
LV2_ATOM_SEQUENCE_FOREACH(self->control_port, ev)
|
LV2_ATOM_SEQUENCE_FOREACH(self->control_port, ev)
|
||||||
{
|
{
|
||||||
|
const int delay = (int)ev->time.frames;
|
||||||
|
|
||||||
// If the received atom is an object/patch message
|
// If the received atom is an object/patch message
|
||||||
if (ev->body.type == self->atom_object_uri)
|
if (ev->body.type == self->atom_object_uri || ev->body.type == self->atom_blank_uri)
|
||||||
{
|
{
|
||||||
const LV2_Atom_Object *obj = (const LV2_Atom_Object *)&ev->body;
|
const LV2_Atom_Object *obj = (const LV2_Atom_Object *)&ev->body;
|
||||||
if (obj->body.otype == self->patch_set_uri)
|
if (obj->body.otype == self->patch_set_uri)
|
||||||
|
|
@ -773,7 +888,60 @@ run(LV2_Handle instance, uint32_t sample_count)
|
||||||
}
|
}
|
||||||
else if (obj->body.otype == self->time_position_uri)
|
else if (obj->body.otype == self->time_position_uri)
|
||||||
{
|
{
|
||||||
// TODO: Handle time position atom
|
const LV2_Atom *bar_atom = NULL;
|
||||||
|
const LV2_Atom *bar_beat_atom = NULL;
|
||||||
|
const LV2_Atom *beat_unit_atom = NULL;
|
||||||
|
const LV2_Atom *beats_per_bar_atom = NULL;
|
||||||
|
const LV2_Atom *beats_per_minute_atom = NULL;
|
||||||
|
const LV2_Atom *speed_atom = NULL;
|
||||||
|
|
||||||
|
lv2_atom_object_get(
|
||||||
|
obj,
|
||||||
|
self->time_bar_uri, &bar_atom,
|
||||||
|
self->time_bar_beat_uri, &bar_beat_atom,
|
||||||
|
self->time_beats_per_bar_uri, &beats_per_bar_atom,
|
||||||
|
self->time_beats_per_minute_uri, &beats_per_minute_atom,
|
||||||
|
self->time_beat_unit_uri, &beat_unit_atom,
|
||||||
|
self->time_speed_uri, &speed_atom,
|
||||||
|
0);
|
||||||
|
|
||||||
|
int updates = 0;
|
||||||
|
|
||||||
|
int64_t bar;
|
||||||
|
double bar_beat;
|
||||||
|
if (sfizz_atom_extract_integer(self, bar_atom, &bar)) {
|
||||||
|
self->bar = (int)bar;
|
||||||
|
updates |= SFIZZ_TIMEINFO_POSITION;
|
||||||
|
}
|
||||||
|
if (sfizz_atom_extract_real(self, bar_beat_atom, &bar_beat)) {
|
||||||
|
self->bar_beat = (float)bar_beat;
|
||||||
|
updates |= SFIZZ_TIMEINFO_POSITION;
|
||||||
|
}
|
||||||
|
|
||||||
|
double beats_per_bar;
|
||||||
|
int64_t beat_unit;
|
||||||
|
if (sfizz_atom_extract_real(self, beats_per_bar_atom, &beats_per_bar)) {
|
||||||
|
self->beats_per_bar = (int)beats_per_bar;
|
||||||
|
updates |= SFIZZ_TIMEINFO_SIGNATURE;
|
||||||
|
}
|
||||||
|
if (sfizz_atom_extract_integer(self, beat_unit_atom, &beat_unit)) {
|
||||||
|
self->beat_unit = (int)beat_unit;
|
||||||
|
updates |= SFIZZ_TIMEINFO_SIGNATURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
double tempo;
|
||||||
|
if (sfizz_atom_extract_real(self, beats_per_minute_atom, &tempo)) {
|
||||||
|
self->bpm_tempo = (float)tempo;
|
||||||
|
updates |= SFIZZ_TIMEINFO_TEMPO;
|
||||||
|
}
|
||||||
|
|
||||||
|
double speed;
|
||||||
|
if (sfizz_atom_extract_real(self, speed_atom, &speed)) {
|
||||||
|
self->speed = (float)speed;
|
||||||
|
updates |= SFIZZ_TIMEINFO_SPEED;
|
||||||
|
}
|
||||||
|
|
||||||
|
sfizz_lv2_update_timeinfo(self, delay, updates);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -802,6 +970,12 @@ run(LV2_Handle instance, uint32_t sample_count)
|
||||||
sfizz_lv2_check_preload_size(self);
|
sfizz_lv2_check_preload_size(self);
|
||||||
sfizz_lv2_check_oversampling(self);
|
sfizz_lv2_check_oversampling(self);
|
||||||
sfizz_lv2_check_num_voices(self);
|
sfizz_lv2_check_num_voices(self);
|
||||||
|
*(self->active_voices_port) = sfizz_get_num_active_voices(self->synth);
|
||||||
|
*(self->num_curves_port) = sfizz_get_num_curves(self->synth);
|
||||||
|
*(self->num_masters_port) = sfizz_get_num_masters(self->synth);
|
||||||
|
*(self->num_groups_port) = sfizz_get_num_groups(self->synth);
|
||||||
|
*(self->num_regions_port) = sfizz_get_num_regions(self->synth);
|
||||||
|
*(self->num_samples_port) = sfizz_get_num_preloaded_samples(self->synth);
|
||||||
|
|
||||||
// Log the buffer usage
|
// Log the buffer usage
|
||||||
self->sample_counter += (int)sample_count;
|
self->sample_counter += (int)sample_count;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||||
@prefix state: <http://lv2plug.in/ns/ext/state#> .
|
@prefix state: <http://lv2plug.in/ns/ext/state#> .
|
||||||
@prefix time: <http://lv2plug.in/ns/ext/time#> .
|
@prefix time: <http://lv2plug.in/ns/ext/time#> .
|
||||||
|
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||||
@prefix units: <http://lv2plug.in/ns/extensions/units#> .
|
@prefix units: <http://lv2plug.in/ns/extensions/units#> .
|
||||||
@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
|
@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
|
||||||
@prefix work: <http://lv2plug.in/ns/ext/worker#> .
|
@prefix work: <http://lv2plug.in/ns/ext/worker#> .
|
||||||
|
|
@ -35,6 +36,12 @@ midnam:update a lv2:Feature .
|
||||||
"Accordage"@fr ,
|
"Accordage"@fr ,
|
||||||
"Accordatura"@it .
|
"Accordatura"@it .
|
||||||
|
|
||||||
|
<@LV2PLUGIN_URI@#status>
|
||||||
|
a pg:Group ;
|
||||||
|
lv2:symbol "status" ;
|
||||||
|
lv2:name "status",
|
||||||
|
"Statut"@fr .
|
||||||
|
|
||||||
<@LV2PLUGIN_URI@:sfzfile>
|
<@LV2PLUGIN_URI@:sfzfile>
|
||||||
a lv2:Parameter ;
|
a lv2:Parameter ;
|
||||||
rdfs:label "SFZ file",
|
rdfs:label "SFZ file",
|
||||||
|
|
@ -77,8 +84,10 @@ midnam:update a lv2:Feature .
|
||||||
opts:supportedOption param:sampleRate ;
|
opts:supportedOption param:sampleRate ;
|
||||||
opts:supportedOption bufsize:maxBlockLength, bufsize:nominalBlockLength ;
|
opts:supportedOption bufsize:maxBlockLength, bufsize:nominalBlockLength ;
|
||||||
|
|
||||||
patch:writable <@LV2PLUGIN_URI@:sfzfile> ;
|
@LV2PLUGIN_IF_ENABLE_UI@ui:ui <@LV2PLUGIN_URI@#ui> ;
|
||||||
patch:writable <@LV2PLUGIN_URI@:tuningfile> ;
|
|
||||||
|
patch:writable <@LV2PLUGIN_URI@:sfzfile> ,
|
||||||
|
<@LV2PLUGIN_URI@:tuningfile> ;
|
||||||
|
|
||||||
lv2:port [
|
lv2:port [
|
||||||
a lv2:InputPort, atom:AtomPort ;
|
a lv2:InputPort, atom:AtomPort ;
|
||||||
|
|
@ -87,7 +96,8 @@ midnam:update a lv2:Feature .
|
||||||
lv2:designation lv2:control ;
|
lv2:designation lv2:control ;
|
||||||
lv2:index 0 ;
|
lv2:index 0 ;
|
||||||
lv2:symbol "control" ;
|
lv2:symbol "control" ;
|
||||||
lv2:name "Control"
|
lv2:name "Control",
|
||||||
|
"Contrôle"@fr ;
|
||||||
] , [
|
] , [
|
||||||
a lv2:OutputPort, atom:AtomPort ;
|
a lv2:OutputPort, atom:AtomPort ;
|
||||||
atom:bufferType atom:Sequence ;
|
atom:bufferType atom:Sequence ;
|
||||||
|
|
@ -95,7 +105,8 @@ midnam:update a lv2:Feature .
|
||||||
lv2:designation lv2:control ;
|
lv2:designation lv2:control ;
|
||||||
lv2:index 1 ;
|
lv2:index 1 ;
|
||||||
lv2:symbol "notify" ;
|
lv2:symbol "notify" ;
|
||||||
lv2:name "Notify" ;
|
lv2:name "Notify",
|
||||||
|
"Notification"@fr ;
|
||||||
] , [
|
] , [
|
||||||
a lv2:AudioPort, lv2:OutputPort ;
|
a lv2:AudioPort, lv2:OutputPort ;
|
||||||
lv2:index 2 ;
|
lv2:index 2 ;
|
||||||
|
|
@ -291,4 +302,70 @@ midnam:update a lv2:Feature .
|
||||||
lv2:minimum 0.0 ;
|
lv2:minimum 0.0 ;
|
||||||
lv2:maximum 1.0 ;
|
lv2:maximum 1.0 ;
|
||||||
units:unit units:coef
|
units:unit units:coef
|
||||||
|
] , [
|
||||||
|
a lv2:OutputPort, lv2:ControlPort ;
|
||||||
|
lv2:index 12 ;
|
||||||
|
lv2:symbol "active_voices" ;
|
||||||
|
lv2:name "Active voices",
|
||||||
|
"Voix utilisées"@fr ;
|
||||||
|
pg:group <@LV2PLUGIN_URI@#status> ;
|
||||||
|
lv2:portProperty lv2:integer ;
|
||||||
|
lv2:default 0 ;
|
||||||
|
lv2:minimum 0 ;
|
||||||
|
lv2:maximum 256 ;
|
||||||
|
] , [
|
||||||
|
a lv2:OutputPort, lv2:ControlPort ;
|
||||||
|
lv2:index 13 ;
|
||||||
|
lv2:symbol "num_curves" ;
|
||||||
|
lv2:name "Number of curves",
|
||||||
|
"Nombre de courbes"@fr ;
|
||||||
|
pg:group <@LV2PLUGIN_URI@#status> ;
|
||||||
|
lv2:portProperty lv2:integer ;
|
||||||
|
lv2:default 0 ;
|
||||||
|
lv2:minimum 0 ;
|
||||||
|
lv2:maximum 65535 ;
|
||||||
|
] , [
|
||||||
|
a lv2:OutputPort, lv2:ControlPort ;
|
||||||
|
lv2:index 14 ;
|
||||||
|
lv2:symbol "num_masters" ;
|
||||||
|
lv2:name "Number of masters",
|
||||||
|
"Nombre de maîtres"@fr ;
|
||||||
|
pg:group <@LV2PLUGIN_URI@#status> ;
|
||||||
|
lv2:portProperty lv2:integer ;
|
||||||
|
lv2:default 0 ;
|
||||||
|
lv2:minimum 0 ;
|
||||||
|
lv2:maximum 65535 ;
|
||||||
|
] , [
|
||||||
|
a lv2:OutputPort, lv2:ControlPort ;
|
||||||
|
lv2:index 15 ;
|
||||||
|
lv2:symbol "num_groups" ;
|
||||||
|
lv2:name "Number of groups",
|
||||||
|
"Nombre de groupes"@fr ;
|
||||||
|
pg:group <@LV2PLUGIN_URI@#status> ;
|
||||||
|
lv2:portProperty lv2:integer ;
|
||||||
|
lv2:default 0 ;
|
||||||
|
lv2:minimum 0 ;
|
||||||
|
lv2:maximum 65535 ;
|
||||||
|
] , [
|
||||||
|
a lv2:OutputPort, lv2:ControlPort ;
|
||||||
|
lv2:index 16 ;
|
||||||
|
lv2:symbol "num_regions" ;
|
||||||
|
lv2:name "Number of regions",
|
||||||
|
"Nombre de régions"@fr ;
|
||||||
|
pg:group <@LV2PLUGIN_URI@#status> ;
|
||||||
|
lv2:portProperty lv2:integer ;
|
||||||
|
lv2:default 0 ;
|
||||||
|
lv2:minimum 0 ;
|
||||||
|
lv2:maximum 65535 ;
|
||||||
|
] , [
|
||||||
|
a lv2:OutputPort, lv2:ControlPort ;
|
||||||
|
lv2:index 17 ;
|
||||||
|
lv2:symbol "num_samples" ;
|
||||||
|
lv2:name "Number of samples",
|
||||||
|
"Nombre d'échantillons"@fr ;
|
||||||
|
pg:group <@LV2PLUGIN_URI@#status> ;
|
||||||
|
lv2:portProperty lv2:integer ;
|
||||||
|
lv2:default 0 ;
|
||||||
|
lv2:minimum 0 ;
|
||||||
|
lv2:maximum 65535 ;
|
||||||
] .
|
] .
|
||||||
|
|
|
||||||
43
lv2/sfizz_lv2.h
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define MAX_PATH_SIZE 1024
|
||||||
|
|
||||||
|
#define SFIZZ_URI "http://sfztools.github.io/sfizz"
|
||||||
|
#define SFIZZ_UI_URI "http://sfztools.github.io/sfizz#ui"
|
||||||
|
#define SFIZZ_PREFIX SFIZZ_URI "#"
|
||||||
|
#define SFIZZ__sfzFile SFIZZ_URI ":" "sfzfile"
|
||||||
|
#define SFIZZ__tuningfile SFIZZ_URI ":" "tuningfile"
|
||||||
|
#define SFIZZ__numVoices SFIZZ_URI ":" "numvoices"
|
||||||
|
#define SFIZZ__preloadSize SFIZZ_URI ":" "preload_size"
|
||||||
|
#define SFIZZ__oversampling SFIZZ_URI ":" "oversampling"
|
||||||
|
// These ones are just for the worker
|
||||||
|
#define SFIZZ__logStatus SFIZZ_URI ":" "log_status"
|
||||||
|
#define SFIZZ__checkModification SFIZZ_URI ":" "check_modification"
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SFIZZ_CONTROL = 0,
|
||||||
|
SFIZZ_NOTIFY = 1,
|
||||||
|
SFIZZ_LEFT = 2,
|
||||||
|
SFIZZ_RIGHT = 3,
|
||||||
|
SFIZZ_VOLUME = 4,
|
||||||
|
SFIZZ_POLYPHONY = 5,
|
||||||
|
SFIZZ_OVERSAMPLING = 6,
|
||||||
|
SFIZZ_PRELOAD = 7,
|
||||||
|
SFIZZ_FREEWHEELING = 8,
|
||||||
|
SFIZZ_SCALA_ROOT_KEY = 9,
|
||||||
|
SFIZZ_TUNING_FREQUENCY = 10,
|
||||||
|
SFIZZ_STRETCH_TUNING = 11,
|
||||||
|
SFIZZ_ACTIVE_VOICES = 12,
|
||||||
|
SFIZZ_NUM_CURVES = 13,
|
||||||
|
SFIZZ_NUM_MASTERS = 14,
|
||||||
|
SFIZZ_NUM_GROUPS = 15,
|
||||||
|
SFIZZ_NUM_REGIONS = 16,
|
||||||
|
SFIZZ_NUM_SAMPLES = 17,
|
||||||
|
};
|
||||||