Merge pull request #397 from jpcima/editor-vstgui-lv2
Editor vstgui lv2
This commit is contained in:
commit
acce5d44f5
46 changed files with 2685 additions and 1116 deletions
2
.gitmodules
vendored
2
.gitmodules
vendored
|
|
@ -16,6 +16,6 @@
|
|||
url = https://github.com/sfztools/vst3_public_sdk.git
|
||||
shallow = true
|
||||
[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
|
||||
shallow = true
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ jobs:
|
|||
env:
|
||||
- INSTALL_DIR="sfizz-plugins-${TRAVIS_BRANCH}-${TRAVIS_OS_NAME}-${TRAVIS_CPU_ARCH}"
|
||||
- ENABLE_VST_PLUGIN=OFF
|
||||
- ENABLE_LV2_UI=OFF
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
|
|
@ -125,6 +126,7 @@ jobs:
|
|||
env:
|
||||
- INSTALL_DIR="sfizz-plugins-${TRAVIS_BRANCH}-${TRAVIS_OS_NAME}-${TRAVIS_CPU_ARCH}"
|
||||
- ENABLE_VST_PLUGIN=ON
|
||||
- ENABLE_LV2_UI=ON
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ buildenv make DESTDIR=${PWD}/${INSTALL_DIR} install
|
|||
|
||||
# Bundle LV2 dependencies
|
||||
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"
|
||||
|
||||
# Bundle VST3 dependencies
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ if [[ ${CROSS_COMPILE} == "mingw32" ]]; then
|
|||
-DENABLE_LTO=OFF \
|
||||
-DSFIZZ_JACK=OFF \
|
||||
-DSFIZZ_VST=ON \
|
||||
-DSFIZZ_STATIC_LIBSNDFILE=ON \
|
||||
-DSFIZZ_STATIC_DEPENDENCIES=ON \
|
||||
-DCMAKE_CXX_STANDARD=17 \
|
||||
..
|
||||
buildenv make -j$(nproc)
|
||||
|
|
@ -18,7 +18,7 @@ elif [[ ${CROSS_COMPILE} == "mingw64" ]]; then
|
|||
-DENABLE_LTO=OFF \
|
||||
-DSFIZZ_JACK=OFF \
|
||||
-DSFIZZ_VST=ON \
|
||||
-DSFIZZ_STATIC_LIBSNDFILE=ON \
|
||||
-DSFIZZ_STATIC_DEPENDENCIES=ON \
|
||||
-DCMAKE_CXX_STANDARD=17 \
|
||||
..
|
||||
buildenv make -j$(nproc)
|
||||
|
|
|
|||
|
|
@ -7,5 +7,5 @@ mkdir -p build/${INSTALL_DIR} && cd build
|
|||
|
||||
buildenv mod-plugin-builder /usr/local/bin/cmake \
|
||||
-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$(nproc)
|
||||
|
|
|
|||
|
|
@ -5,9 +5,10 @@ mkdir -p build/${INSTALL_DIR} && cd build
|
|||
cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
-DSFIZZ_JACK=OFF \
|
||||
-DSFIZZ_VST="$ENABLE_VST_PLUGIN" \
|
||||
-DSFIZZ_LV2_UI="$ENABLE_LV2_UI" \
|
||||
-DSFIZZ_TESTS=OFF \
|
||||
-DSFIZZ_SHARED=OFF \
|
||||
-DSFIZZ_STATIC_LIBSNDFILE=ON \
|
||||
-DSFIZZ_STATIC_DEPENDENCIES=ON \
|
||||
-DCMAKE_CXX_STANDARD=17 \
|
||||
..
|
||||
make -j$(nproc)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ cmake -DCMAKE_BUILD_TYPE=Release \
|
|||
-DSFIZZ_JACK=OFF \
|
||||
-DSFIZZ_TESTS=ON \
|
||||
-DSFIZZ_SHARED=OFF \
|
||||
-DSFIZZ_STATIC_LIBSNDFILE=OFF \
|
||||
-DSFIZZ_STATIC_DEPENDENCIES=OFF \
|
||||
-DSFIZZ_LV2=OFF \
|
||||
-DCMAKE_CXX_STANDARD=17 \
|
||||
..
|
||||
|
|
|
|||
|
|
@ -19,16 +19,11 @@ include (SfizzConfig)
|
|||
# Build Options
|
||||
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 (SFIZZ_JACK "Enable JACK stand-alone build [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_UI "Enable LV2 plug-in user interface [default: ON]" ON)
|
||||
option (SFIZZ_VST "Enable VST 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)
|
||||
|
|
@ -36,7 +31,7 @@ option (SFIZZ_TESTS "Enable tests 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_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)
|
||||
|
||||
# Don't use IPO in non Release builds
|
||||
|
|
@ -51,6 +46,10 @@ add_subdirectory (src)
|
|||
# Optional targets
|
||||
add_subdirectory (clients)
|
||||
|
||||
if ((SFIZZ_LV2 AND SFIZZ_LV2_UI) OR SFIZZ_VST)
|
||||
add_subdirectory (editor)
|
||||
endif()
|
||||
|
||||
if (SFIZZ_LV2)
|
||||
add_subdirectory (lv2)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@ build_script:
|
|||
- cmd: cmake --build . --config Release -j
|
||||
|
||||
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%==x64 set RELEASE_ARCH=x64
|
||||
- cmd: 7z a sfizz-lv2-%APPVEYOR_REPO_TAG_NAME%-%RELEASE_ARCH%-msvc.zip sfizz.lv2
|
||||
|
|
|
|||
|
|
@ -14,6 +14,22 @@ else()
|
|||
set (LV2PLUGIN_SPDX_LICENSE_ID "ISC")
|
||||
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)
|
||||
set (LV2PLUGIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lv2" CACHE STRING
|
||||
"Install destination for LV2 bundle [default: ${CMAKE_INSTALL_PREFIX}/lv2}]")
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@ if (WIN32)
|
|||
add_compile_definitions(_WIN32_WINNT=0x601)
|
||||
endif()
|
||||
|
||||
# Do not define macros `min` and `max`
|
||||
if (WIN32)
|
||||
add_compile_definitions(NOMINMAX)
|
||||
endif()
|
||||
|
||||
# The variable CMAKE_SYSTEM_PROCESSOR is incorrect on Visual studio...
|
||||
# see https://gitlab.kitware.com/cmake/cmake/issues/15170
|
||||
|
||||
|
|
@ -48,6 +53,7 @@ function(sfizz_enable_fast_math NAME)
|
|||
endif()
|
||||
endfunction()
|
||||
|
||||
# The sndfile library
|
||||
add_library(sfizz-sndfile INTERFACE)
|
||||
|
||||
if (SFIZZ_USE_VCPKG OR CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
|
|
@ -59,11 +65,12 @@ else()
|
|||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(SNDFILE "sndfile" REQUIRED)
|
||||
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})
|
||||
else()
|
||||
target_link_libraries(sfizz-sndfile INTERFACE ${SNDFILE_LIBRARIES})
|
||||
endif()
|
||||
link_directories(${SNDFILE_LIBRARY_DIRS})
|
||||
endif()
|
||||
|
||||
|
||||
|
|
@ -112,12 +119,13 @@ Build using LTO: ${ENABLE_LTO}
|
|||
Build as shared library: ${SFIZZ_SHARED}
|
||||
Build JACK stand-alone client: ${SFIZZ_JACK}
|
||||
Build LV2 plug-in: ${SFIZZ_LV2}
|
||||
Build LV2 user interface: ${SFIZZ_LV2_UI}
|
||||
Build VST plug-in: ${SFIZZ_VST}
|
||||
Build AU plug-in: ${SFIZZ_AU}
|
||||
Build benchmarks: ${SFIZZ_BENCHMARKS}
|
||||
Build tests: ${SFIZZ_TESTS}
|
||||
Use vcpkg: ${SFIZZ_USE_VCPKG}
|
||||
Statically link libsndfile: ${SFIZZ_STATIC_LIBSNDFILE}
|
||||
Statically link dependencies: ${SFIZZ_STATIC_DEPENDENCIES}
|
||||
Link libatomic: ${SFIZZ_LINK_LIBATOMIC}
|
||||
Use clang libc++: ${USE_LIBCPP}
|
||||
Release asserts: ${SFIZZ_RELEASE_ASSERTS}
|
||||
|
|
|
|||
21
editor/CMakeLists.txt
Normal file
21
editor/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
set(VSTGUI_BASEDIR "${CMAKE_CURRENT_SOURCE_DIR}/external/vstgui4")
|
||||
include("cmake/Vstgui.cmake")
|
||||
|
||||
set(EDITOR_RESOURCES
|
||||
logo.png
|
||||
PARENT_SCOPE)
|
||||
|
||||
# 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/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)
|
||||
229
editor/cmake/Vstgui.cmake
Normal file
229
editor/cmake/Vstgui.cmake
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
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/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/win32textedit.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/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/linuxstring.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
|
||||
find_library(OPENGL32_LIBRARY "opengl32")
|
||||
find_library(D2D1_LIBRARY "d2d1")
|
||||
find_library(DWRITE_LIBRARY "dwrite")
|
||||
find_library(DWMAPI_LIBRARY "dwmapi")
|
||||
find_library(WINDOWSCODECS_LIBRARY "windowscodecs")
|
||||
find_library(SHLWAPI_LIBRARY "shlwapi")
|
||||
target_link_libraries(sfizz-vstgui PRIVATE
|
||||
"${OPENGL32_LIBRARY}"
|
||||
"${D2D1_LIBRARY}"
|
||||
"${DWRITE_LIBRARY}"
|
||||
"${DWMAPI_LIBRARY}"
|
||||
"${WINDOWSCODECS_LIBRARY}"
|
||||
"${SHLWAPI_LIBRARY}")
|
||||
endif()
|
||||
elseif(APPLE)
|
||||
find_library(APPLE_COREFOUNDATION_LIBRARY "CoreFoundation")
|
||||
find_library(APPLE_FOUNDATION_LIBRARY "Foundation")
|
||||
find_library(APPLE_COCOA_LIBRARY "Cocoa")
|
||||
find_library(APPLE_OPENGL_LIBRARY "OpenGL")
|
||||
find_library(APPLE_ACCELERATE_LIBRARY "Accelerate")
|
||||
find_library(APPLE_QUARTZCORE_LIBRARY "QuartzCore")
|
||||
find_library(APPLE_CARBON_LIBRARY "Carbon")
|
||||
find_library(APPLE_AUDIOTOOLBOX_LIBRARY "AudioToolbox")
|
||||
find_library(APPLE_COREAUDIO_LIBRARY "CoreAudio")
|
||||
find_library(APPLE_COREMIDI_LIBRARY "CoreMIDI")
|
||||
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)
|
||||
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})
|
||||
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})
|
||||
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)
|
||||
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
1
editor/external/vstgui4
vendored
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 7316f9fb2891b9f0e2a408cfbf4ec35aeec268bd
|
||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
32
editor/src/editor/EditIds.cpp
Normal file
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
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
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;
|
||||
};
|
||||
977
editor/src/editor/Editor.cpp
Normal file
977
editor/src/editor/Editor.cpp
Normal file
|
|
@ -0,0 +1,977 @@
|
|||
// 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 "Editor.h"
|
||||
#include "EditorController.h"
|
||||
#include "EditIds.h"
|
||||
#include "GUIComponents.h"
|
||||
#include <absl/strings/string_view.h>
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
|
||||
#include "utility/vstgui_before.h"
|
||||
#include "vstgui/vstgui.h"
|
||||
#include "utility/vstgui_after.h"
|
||||
|
||||
using namespace VSTGUI;
|
||||
|
||||
const int Editor::viewWidth { 482 };
|
||||
const int Editor::viewHeight { 225 };
|
||||
|
||||
struct Editor::Impl : EditorController::Receiver, IControlListener {
|
||||
EditorController* ctrl_ = nullptr;
|
||||
CFrame* frame_ = nullptr;
|
||||
SharedPointer<CViewContainer> view_;
|
||||
|
||||
enum {
|
||||
kPanelGeneral,
|
||||
// kPanelControls,
|
||||
kPanelSettings,
|
||||
kPanelTuning,
|
||||
kPanelInfo,
|
||||
kNumPanels,
|
||||
};
|
||||
|
||||
unsigned activePanel_ = 0;
|
||||
CViewContainer* subPanels_[kNumPanels] = {};
|
||||
|
||||
enum {
|
||||
kTagLoadSfzFile,
|
||||
kTagSetVolume,
|
||||
kTagSetNumVoices,
|
||||
kTagSetOversampling,
|
||||
kTagSetPreloadSize,
|
||||
kTagLoadScalaFile,
|
||||
kTagSetScalaRootKey,
|
||||
kTagSetTuningFrequency,
|
||||
kTagSetStretchedTuning,
|
||||
kTagFirstChangePanel,
|
||||
kTagLastChangePanel = kTagFirstChangePanel + kNumPanels - 1,
|
||||
};
|
||||
|
||||
CTextLabel* sfzFileLabel_ = nullptr;
|
||||
CTextLabel* scalaFileLabel_ = nullptr;
|
||||
CSliderBase *volumeSlider_ = nullptr;
|
||||
CTextLabel* volumeLabel_ = nullptr;
|
||||
CSliderBase *numVoicesSlider_ = nullptr;
|
||||
CTextLabel* numVoicesLabel_ = nullptr;
|
||||
CSliderBase *oversamplingSlider_ = nullptr;
|
||||
CTextLabel* oversamplingLabel_ = nullptr;
|
||||
CSliderBase *preloadSizeSlider_ = nullptr;
|
||||
CTextLabel* preloadSizeLabel_ = nullptr;
|
||||
CSliderBase *scalaRootKeySlider_ = nullptr;
|
||||
CTextLabel* scalaRootKeyLabel_ = nullptr;
|
||||
CSliderBase *tuningFrequencySlider_ = nullptr;
|
||||
CTextLabel* tuningFrequencyLabel_ = nullptr;
|
||||
CSliderBase *stretchedTuningSlider_ = nullptr;
|
||||
CTextLabel* stretchedTuningLabel_ = nullptr;
|
||||
|
||||
CTextLabel* infoCurvesLabel_ = nullptr;
|
||||
CTextLabel* infoMastersLabel_ = nullptr;
|
||||
CTextLabel* infoGroupsLabel_ = nullptr;
|
||||
CTextLabel* infoRegionsLabel_ = nullptr;
|
||||
CTextLabel* infoSamplesLabel_ = nullptr;
|
||||
CTextLabel* infoVoicesLabel_ = nullptr;
|
||||
|
||||
void uiReceiveValue(EditId id, const EditValue& v) override;
|
||||
|
||||
void createFrameContents();
|
||||
|
||||
template <class Control>
|
||||
void adjustMinMaxToEditRange(Control* c, EditId id)
|
||||
{
|
||||
const EditRange er = EditRange::get(id);
|
||||
c->setMin(er.min);
|
||||
c->setMax(er.max);
|
||||
c->setDefaultValue(er.def);
|
||||
}
|
||||
|
||||
void chooseSfzFile();
|
||||
void chooseScalaFile();
|
||||
|
||||
void updateSfzFileLabel(const std::string& filePath);
|
||||
void updateScalaFileLabel(const std::string& filePath);
|
||||
static void updateLabelWithFileName(CTextLabel* label, const std::string& filePath);
|
||||
void updateVolumeLabel(float volume);
|
||||
void updateNumVoicesLabel(int numVoices);
|
||||
void updateOversamplingLabel(int oversamplingLog2);
|
||||
void updatePreloadSizeLabel(int preloadSize);
|
||||
void updateScalaRootKeyLabel(int rootKey);
|
||||
void updateTuningFrequencyLabel(float tuningFrequency);
|
||||
void updateStretchedTuningLabel(float stretchedTuning);
|
||||
|
||||
void setActivePanel(unsigned panelId);
|
||||
|
||||
static void formatLabel(CTextLabel* label, const char* fmt, ...);
|
||||
static void vformatLabel(CTextLabel* label, const char* fmt, va_list ap);
|
||||
|
||||
// IControlListener
|
||||
void valueChanged(CControl* ctl) override;
|
||||
void enterOrLeaveEdit(CControl* ctl, bool enter);
|
||||
void controlBeginEdit(CControl* ctl) override;
|
||||
void controlEndEdit(CControl* ctl) override;
|
||||
};
|
||||
|
||||
Editor::Editor(EditorController& ctrl)
|
||||
: impl_(new Impl)
|
||||
{
|
||||
Impl& impl = *impl_;
|
||||
|
||||
impl.ctrl_ = &ctrl;
|
||||
|
||||
ctrl.decorate(&impl);
|
||||
|
||||
impl.createFrameContents();
|
||||
}
|
||||
|
||||
Editor::~Editor()
|
||||
{
|
||||
Impl& impl = *impl_;
|
||||
|
||||
EditorController& ctrl = *impl.ctrl_;
|
||||
ctrl.decorate(nullptr);
|
||||
}
|
||||
|
||||
void Editor::open(CFrame& frame)
|
||||
{
|
||||
Impl& impl = *impl_;
|
||||
|
||||
impl.frame_ = &frame;
|
||||
frame.addView(impl.view_.get());
|
||||
}
|
||||
|
||||
void Editor::close()
|
||||
{
|
||||
Impl& impl = *impl_;
|
||||
|
||||
if (impl.frame_) {
|
||||
impl.frame_->removeView(impl.view_.get());
|
||||
impl.frame_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::Impl::uiReceiveValue(EditId id, const EditValue& v)
|
||||
{
|
||||
switch (id) {
|
||||
case EditId::SfzFile:
|
||||
{
|
||||
const std::string& value = v.to_string();
|
||||
updateSfzFileLabel(value);
|
||||
}
|
||||
break;
|
||||
case EditId::Volume:
|
||||
{
|
||||
const float value = v.to_float();
|
||||
if (volumeSlider_)
|
||||
volumeSlider_->setValue(value);
|
||||
updateVolumeLabel(value);
|
||||
}
|
||||
break;
|
||||
case EditId::Polyphony:
|
||||
{
|
||||
const int value = static_cast<int>(v.to_float());
|
||||
if (numVoicesSlider_)
|
||||
numVoicesSlider_->setValue(value);
|
||||
updateNumVoicesLabel(value);
|
||||
}
|
||||
break;
|
||||
case EditId::Oversampling:
|
||||
{
|
||||
const int value = static_cast<int>(v.to_float());
|
||||
|
||||
int log2Value = 0;
|
||||
for (int f = value; f > 1; f /= 2)
|
||||
++log2Value;
|
||||
|
||||
if (oversamplingSlider_)
|
||||
oversamplingSlider_->setValue(log2Value);
|
||||
updateOversamplingLabel(log2Value);
|
||||
}
|
||||
break;
|
||||
case EditId::PreloadSize:
|
||||
{
|
||||
const int value = static_cast<int>(v.to_float());
|
||||
if (preloadSizeSlider_)
|
||||
preloadSizeSlider_->setValue(value);
|
||||
updatePreloadSizeLabel(value);
|
||||
}
|
||||
break;
|
||||
case EditId::ScalaFile:
|
||||
{
|
||||
const std::string& value = v.to_string();
|
||||
updateScalaFileLabel(value);
|
||||
}
|
||||
break;
|
||||
case EditId::ScalaRootKey:
|
||||
{
|
||||
const int value = static_cast<int>(v.to_float());
|
||||
if (scalaRootKeySlider_)
|
||||
scalaRootKeySlider_->setValue(value);
|
||||
updateScalaRootKeyLabel(value);
|
||||
}
|
||||
break;
|
||||
case EditId::TuningFrequency:
|
||||
{
|
||||
const float value = v.to_float();
|
||||
if (tuningFrequencySlider_)
|
||||
tuningFrequencySlider_->setValue(value);
|
||||
updateTuningFrequencyLabel(value);
|
||||
}
|
||||
break;
|
||||
case EditId::StretchTuning:
|
||||
{
|
||||
const float value = v.to_float();
|
||||
if (stretchedTuningSlider_)
|
||||
stretchedTuningSlider_->setValue(value);
|
||||
updateStretchedTuningLabel(value);
|
||||
}
|
||||
break;
|
||||
case EditId::UINumCurves:
|
||||
{
|
||||
const int value = static_cast<int>(v.to_float());
|
||||
if (CTextLabel* label = infoCurvesLabel_)
|
||||
formatLabel(label, "%u", value);
|
||||
}
|
||||
break;
|
||||
case EditId::UINumMasters:
|
||||
{
|
||||
const int value = static_cast<int>(v.to_float());
|
||||
if (CTextLabel* label = infoMastersLabel_)
|
||||
formatLabel(label, "%u", value);
|
||||
}
|
||||
break;
|
||||
case EditId::UINumGroups:
|
||||
{
|
||||
const int value = static_cast<int>(v.to_float());
|
||||
if (CTextLabel* label = infoGroupsLabel_)
|
||||
formatLabel(label, "%u", value);
|
||||
}
|
||||
break;
|
||||
case EditId::UINumRegions:
|
||||
{
|
||||
const int value = static_cast<int>(v.to_float());
|
||||
if (CTextLabel* label = infoRegionsLabel_)
|
||||
formatLabel(label, "%u", value);
|
||||
}
|
||||
break;
|
||||
case EditId::UINumPreloadedSamples:
|
||||
{
|
||||
const int value = static_cast<int>(v.to_float());
|
||||
if (CTextLabel* label = infoSamplesLabel_)
|
||||
formatLabel(label, "%u", value);
|
||||
}
|
||||
break;
|
||||
case EditId::UINumActiveVoices:
|
||||
{
|
||||
const int value = static_cast<int>(v.to_float());
|
||||
if (CTextLabel* label = infoVoicesLabel_)
|
||||
formatLabel(label, "%u", value);
|
||||
}
|
||||
break;
|
||||
case EditId::UIActivePanel:
|
||||
{
|
||||
const int value = static_cast<int>(v.to_float());
|
||||
setActivePanel(value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::Impl::createFrameContents()
|
||||
{
|
||||
const CRect bounds { 0.0, 0.0, static_cast<CCoord>(viewWidth), static_cast<CCoord>(viewHeight) };
|
||||
CViewContainer* view = new CViewContainer(bounds);
|
||||
view_ = view;
|
||||
|
||||
view->setBackgroundColor(CColor(0xff, 0xff, 0xff));
|
||||
|
||||
SharedPointer<CBitmap> logo { new CBitmap("logo.png") };
|
||||
|
||||
CRect bottomRow = bounds;
|
||||
bottomRow.top = bottomRow.bottom - 30;
|
||||
|
||||
CRect topRow = bounds;
|
||||
topRow.bottom = topRow.top + 30;
|
||||
|
||||
CViewContainer* panel;
|
||||
activePanel_ = 0;
|
||||
|
||||
CRect topLeftLabelBox = topRow;
|
||||
topLeftLabelBox.right -= 20 * kNumPanels;
|
||||
|
||||
// general panel
|
||||
{
|
||||
panel = new CViewContainer(bounds);
|
||||
view->addView(panel);
|
||||
panel->setTransparency(true);
|
||||
|
||||
CKickButton* sfizzButton = new CKickButton(bounds, this, kTagLoadSfzFile, logo);
|
||||
panel->addView(sfizzButton);
|
||||
|
||||
CTextLabel* topLeftLabel = new CTextLabel(topLeftLabelBox, "No file loaded");
|
||||
topLeftLabel->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
topLeftLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
panel->addView(topLeftLabel);
|
||||
sfzFileLabel_ = topLeftLabel;
|
||||
|
||||
subPanels_[kPanelGeneral] = panel;
|
||||
}
|
||||
|
||||
// settings panel
|
||||
{
|
||||
panel = new CViewContainer(bounds);
|
||||
view->addView(panel);
|
||||
panel->setTransparency(true);
|
||||
|
||||
CTextLabel* topLeftLabel = new CTextLabel(topLeftLabelBox, "Settings");
|
||||
topLeftLabel->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
topLeftLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
panel->addView(topLeftLabel);
|
||||
|
||||
CRect row = topRow;
|
||||
row.top += 45.0;
|
||||
row.bottom += 45.0;
|
||||
row.left += 20.0;
|
||||
row.right -= 20.0;
|
||||
|
||||
static const CCoord interRow = 35.0;
|
||||
static const CCoord interColumn = 20.0;
|
||||
static const int numColumns = 3;
|
||||
|
||||
auto nthColumn = [&row](int colIndex) -> CRect {
|
||||
CRect div = row;
|
||||
CCoord columnWidth = (div.right - div.left + interColumn) / numColumns - interColumn;
|
||||
div.left = div.left + colIndex * (columnWidth + interColumn);
|
||||
div.right = div.left + columnWidth;
|
||||
return div;
|
||||
};
|
||||
|
||||
CTextLabel* label;
|
||||
SimpleSlider* slider;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Volume");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
slider = new SimpleSlider(nthColumn(1), this, kTagSetVolume);
|
||||
panel->addView(slider);
|
||||
adjustMinMaxToEditRange(slider, EditId::Volume);
|
||||
volumeSlider_ = slider;
|
||||
label = new CTextLabel(nthColumn(2), "");
|
||||
volumeLabel_ = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Polyphony");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
slider = new SimpleSlider(nthColumn(1), this, kTagSetNumVoices);
|
||||
panel->addView(slider);
|
||||
adjustMinMaxToEditRange(slider, EditId::Polyphony);
|
||||
numVoicesSlider_ = slider;
|
||||
label = new CTextLabel(nthColumn(2), "");
|
||||
numVoicesLabel_ = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Oversampling");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
slider = new SimpleSlider(nthColumn(1), this, kTagSetOversampling);
|
||||
panel->addView(slider);
|
||||
adjustMinMaxToEditRange(slider, EditId::Oversampling);
|
||||
oversamplingSlider_ = slider;
|
||||
label = new CTextLabel(nthColumn(2), "");
|
||||
oversamplingLabel_ = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Preload size");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
slider = new SimpleSlider(nthColumn(1), this, kTagSetPreloadSize);
|
||||
panel->addView(slider);
|
||||
adjustMinMaxToEditRange(slider, EditId::PreloadSize);
|
||||
preloadSizeSlider_ = slider;
|
||||
label = new CTextLabel(nthColumn(2), "");
|
||||
preloadSizeLabel_ = label;
|
||||
panel->addView(label);
|
||||
|
||||
subPanels_[kPanelSettings] = panel;
|
||||
}
|
||||
|
||||
// tuning panel
|
||||
{
|
||||
panel = new CViewContainer(bounds);
|
||||
view->addView(panel);
|
||||
panel->setTransparency(true);
|
||||
|
||||
CTextLabel* topLeftLabel = new CTextLabel(topLeftLabelBox, "Tuning");
|
||||
topLeftLabel->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
topLeftLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
panel->addView(topLeftLabel);
|
||||
|
||||
CRect row = topRow;
|
||||
row.top += 45.0;
|
||||
row.bottom += 45.0;
|
||||
row.left += 20.0;
|
||||
row.right -= 20.0;
|
||||
|
||||
static const CCoord interRow = 35.0;
|
||||
static const CCoord interColumn = 20.0;
|
||||
static const int numColumns = 3;
|
||||
|
||||
auto nthColumn = [&row](int colIndex) -> CRect {
|
||||
CRect div = row;
|
||||
CCoord columnWidth = (div.right - div.left + interColumn) / numColumns - interColumn;
|
||||
div.left = div.left + colIndex * (columnWidth + interColumn);
|
||||
div.right = div.left + columnWidth;
|
||||
return div;
|
||||
};
|
||||
|
||||
CTextLabel* label;
|
||||
SimpleSlider* slider;
|
||||
CTextButton* textbutton;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Scala file");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
textbutton = new CTextButton(nthColumn(1), this, kTagLoadScalaFile, "Choose");
|
||||
panel->addView(textbutton);
|
||||
label = new CTextLabel(nthColumn(2), "");
|
||||
scalaFileLabel_ = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Scala root key");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
slider = new SimpleSlider(nthColumn(1), this, kTagSetScalaRootKey);
|
||||
panel->addView(slider);
|
||||
adjustMinMaxToEditRange(slider, EditId::ScalaRootKey);
|
||||
scalaRootKeySlider_ = slider;
|
||||
label = new CTextLabel(nthColumn(2), "");
|
||||
scalaRootKeyLabel_ = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Tuning frequency");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
slider = new SimpleSlider(nthColumn(1), this, kTagSetTuningFrequency);
|
||||
panel->addView(slider);
|
||||
adjustMinMaxToEditRange(slider, EditId::TuningFrequency);
|
||||
tuningFrequencySlider_ = slider;
|
||||
label = new CTextLabel(nthColumn(2), "");
|
||||
tuningFrequencyLabel_ = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Stretched tuning");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
slider = new SimpleSlider(nthColumn(1), this, kTagSetStretchedTuning);
|
||||
panel->addView(slider);
|
||||
adjustMinMaxToEditRange(slider, EditId::StretchTuning);
|
||||
stretchedTuningSlider_ = slider;
|
||||
label = new CTextLabel(nthColumn(2), "");
|
||||
stretchedTuningLabel_ = label;
|
||||
panel->addView(label);
|
||||
|
||||
subPanels_[kPanelTuning] = panel;
|
||||
}
|
||||
|
||||
// info panel
|
||||
{
|
||||
panel = new CViewContainer(bounds);
|
||||
view->addView(panel);
|
||||
panel->setTransparency(true);
|
||||
|
||||
CTextLabel* topLeftLabel = new CTextLabel(topLeftLabelBox, "Information");
|
||||
topLeftLabel->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
topLeftLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
panel->addView(topLeftLabel);
|
||||
|
||||
CRect row = topRow;
|
||||
row.top += 45.0;
|
||||
row.bottom += 45.0;
|
||||
row.left += 20.0;
|
||||
row.right -= 20.0;
|
||||
|
||||
static const CCoord interRow = 20.0;
|
||||
static const CCoord interColumn = 20.0;
|
||||
static const int numColumns = 3;
|
||||
|
||||
auto nthColumn = [&row](int colIndex) -> CRect {
|
||||
CRect div = row;
|
||||
CCoord columnWidth = (div.right - div.left + interColumn) / numColumns - interColumn;
|
||||
div.left = div.left + colIndex * (columnWidth + interColumn);
|
||||
div.right = div.left + columnWidth;
|
||||
return div;
|
||||
};
|
||||
|
||||
CTextLabel* label;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Curves");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
label = new CTextLabel(nthColumn(1), "");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
infoCurvesLabel_ = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Masters");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
label = new CTextLabel(nthColumn(1), "");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
infoMastersLabel_ = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Groups");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
label = new CTextLabel(nthColumn(1), "");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
infoGroupsLabel_ = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Regions");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
label = new CTextLabel(nthColumn(1), "");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
infoRegionsLabel_ = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Samples");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
label = new CTextLabel(nthColumn(1), "");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
infoSamplesLabel_ = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Voices");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
label = new CTextLabel(nthColumn(1), "");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
infoVoicesLabel_ = label;
|
||||
panel->addView(label);
|
||||
|
||||
subPanels_[kPanelInfo] = panel;
|
||||
}
|
||||
|
||||
// all panels
|
||||
for (unsigned currentPanel = 0; currentPanel < kNumPanels; ++currentPanel) {
|
||||
panel = subPanels_[currentPanel];
|
||||
|
||||
CTextLabel* descLabel = new CTextLabel(
|
||||
bottomRow, "Paul Ferrand and the SFZ Tools work group");
|
||||
descLabel->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
descLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
panel->addView(descLabel);
|
||||
|
||||
for (unsigned i = 0; i < kNumPanels; ++i) {
|
||||
CRect btnRect = topRow;
|
||||
btnRect.left = topRow.right - (kNumPanels - i) * 50;
|
||||
btnRect.right = btnRect.left + 50;
|
||||
|
||||
const char *text;
|
||||
switch (i) {
|
||||
case kPanelGeneral: text = "File"; break;
|
||||
case kPanelSettings: text = "Setup"; break;
|
||||
case kPanelTuning: text = "Tuning"; break;
|
||||
case kPanelInfo: text = "Info"; break;
|
||||
default: text = "?"; break;
|
||||
}
|
||||
|
||||
CTextButton* changePanelButton = new CTextButton(btnRect, this, kTagFirstChangePanel + i, text);
|
||||
panel->addView(changePanelButton);
|
||||
|
||||
changePanelButton->setRoundRadius(0.0);
|
||||
}
|
||||
|
||||
panel->setVisible(currentPanel == activePanel_);
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::Impl::chooseSfzFile()
|
||||
{
|
||||
SharedPointer<CNewFileSelector> fs(CNewFileSelector::create(frame_));
|
||||
|
||||
fs->setTitle("Load SFZ file");
|
||||
fs->setDefaultExtension(CFileExtension("SFZ", "sfz"));
|
||||
|
||||
if (fs->runModal()) {
|
||||
UTF8StringPtr file = fs->getSelectedFile(0);
|
||||
if (file) {
|
||||
std::string str(file);
|
||||
ctrl_->uiSendValue(EditId::SfzFile, str);
|
||||
updateSfzFileLabel(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::Impl::chooseScalaFile()
|
||||
{
|
||||
SharedPointer<CNewFileSelector> fs(CNewFileSelector::create(frame_));
|
||||
|
||||
fs->setTitle("Load Scala file");
|
||||
fs->setDefaultExtension(CFileExtension("SCL", "scl"));
|
||||
|
||||
if (fs->runModal()) {
|
||||
UTF8StringPtr file = fs->getSelectedFile(0);
|
||||
if (file) {
|
||||
std::string str(file);
|
||||
ctrl_->uiSendValue(EditId::ScalaFile, str);
|
||||
updateScalaFileLabel(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::Impl::updateSfzFileLabel(const std::string& filePath)
|
||||
{
|
||||
updateLabelWithFileName(sfzFileLabel_, filePath);
|
||||
}
|
||||
|
||||
void Editor::Impl::updateScalaFileLabel(const std::string& filePath)
|
||||
{
|
||||
updateLabelWithFileName(scalaFileLabel_, filePath);
|
||||
}
|
||||
|
||||
void Editor::Impl::updateLabelWithFileName(CTextLabel* label, const std::string& filePath)
|
||||
{
|
||||
if (!label)
|
||||
return;
|
||||
|
||||
std::string fileName;
|
||||
if (filePath.empty())
|
||||
fileName = "<No file>";
|
||||
else {
|
||||
#if defined (_WIN32)
|
||||
size_t pos = filePath.find_last_of("/\\");
|
||||
#else
|
||||
size_t pos = filePath.rfind('/');
|
||||
#endif
|
||||
fileName = (pos != filePath.npos) ?
|
||||
filePath.substr(pos + 1) : filePath;
|
||||
}
|
||||
label->setText(fileName.c_str());
|
||||
}
|
||||
|
||||
void Editor::Impl::updateVolumeLabel(float volume)
|
||||
{
|
||||
CTextLabel* label = volumeLabel_;
|
||||
if (!label)
|
||||
return;
|
||||
|
||||
char text[64];
|
||||
sprintf(text, "%.1f dB", volume);
|
||||
text[sizeof(text) - 1] = '\0';
|
||||
label->setText(text);
|
||||
}
|
||||
|
||||
void Editor::Impl::updateNumVoicesLabel(int numVoices)
|
||||
{
|
||||
CTextLabel* label = numVoicesLabel_;
|
||||
if (!label)
|
||||
return;
|
||||
|
||||
char text[64];
|
||||
sprintf(text, "%d", numVoices);
|
||||
text[sizeof(text) - 1] = '\0';
|
||||
label->setText(text);
|
||||
}
|
||||
|
||||
void Editor::Impl::updateOversamplingLabel(int oversamplingLog2)
|
||||
{
|
||||
CTextLabel* label = oversamplingLabel_;
|
||||
if (!label)
|
||||
return;
|
||||
|
||||
char text[64];
|
||||
sprintf(text, "%dx", 1 << oversamplingLog2);
|
||||
text[sizeof(text) - 1] = '\0';
|
||||
label->setText(text);
|
||||
}
|
||||
|
||||
void Editor::Impl::updatePreloadSizeLabel(int preloadSize)
|
||||
{
|
||||
CTextLabel* label = preloadSizeLabel_;
|
||||
if (!label)
|
||||
return;
|
||||
|
||||
char text[64];
|
||||
sprintf(text, "%.1f kB", preloadSize * (1.0 / 1024));
|
||||
text[sizeof(text) - 1] = '\0';
|
||||
label->setText(text);
|
||||
}
|
||||
|
||||
void Editor::Impl::updateScalaRootKeyLabel(int rootKey)
|
||||
{
|
||||
CTextLabel* label = scalaRootKeyLabel_;
|
||||
if (!label)
|
||||
return;
|
||||
|
||||
static const char *octNoteNames[12] = {
|
||||
"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B",
|
||||
};
|
||||
|
||||
auto noteName = [](int key) -> std::string
|
||||
{
|
||||
int octNum;
|
||||
int octNoteNum;
|
||||
if (key >= 0) {
|
||||
octNum = key / 12 - 1;
|
||||
octNoteNum = key % 12;
|
||||
}
|
||||
else {
|
||||
octNum = -2 - (key + 1) / -12;
|
||||
octNoteNum = (key % 12 + 12) % 12;
|
||||
}
|
||||
return std::string(octNoteNames[octNoteNum]) + std::to_string(octNum);
|
||||
};
|
||||
|
||||
label->setText(noteName(rootKey));
|
||||
}
|
||||
|
||||
void Editor::Impl::updateTuningFrequencyLabel(float tuningFrequency)
|
||||
{
|
||||
CTextLabel* label = tuningFrequencyLabel_;
|
||||
if (!label)
|
||||
return;
|
||||
|
||||
char text[64];
|
||||
sprintf(text, "%.1f", tuningFrequency);
|
||||
text[sizeof(text) - 1] = '\0';
|
||||
label->setText(text);
|
||||
}
|
||||
|
||||
void Editor::Impl::updateStretchedTuningLabel(float stretchedTuning)
|
||||
{
|
||||
CTextLabel* label = stretchedTuningLabel_;
|
||||
if (!label)
|
||||
return;
|
||||
|
||||
char text[64];
|
||||
sprintf(text, "%.3f", stretchedTuning);
|
||||
text[sizeof(text) - 1] = '\0';
|
||||
label->setText(text);
|
||||
}
|
||||
|
||||
void Editor::Impl::setActivePanel(unsigned panelId)
|
||||
{
|
||||
panelId = std::max(0, std::min(kNumPanels - 1, static_cast<int>(panelId)));
|
||||
|
||||
if (activePanel_ != panelId) {
|
||||
subPanels_[activePanel_]->setVisible(false);
|
||||
activePanel_ = panelId;
|
||||
subPanels_[panelId]->setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::Impl::formatLabel(CTextLabel* label, const char* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vformatLabel(label, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Editor::Impl::vformatLabel(CTextLabel* label, const char* fmt, va_list ap)
|
||||
{
|
||||
char text[256];
|
||||
vsprintf(text, fmt, ap);
|
||||
text[sizeof(text) - 1] = '\0';
|
||||
label->setText(text);
|
||||
}
|
||||
|
||||
void Editor::Impl::valueChanged(CControl* ctl)
|
||||
{
|
||||
int32_t tag = ctl->getTag();
|
||||
float value = ctl->getValue();
|
||||
EditorController& ctrl = *ctrl_;
|
||||
|
||||
switch (tag) {
|
||||
case kTagLoadSfzFile:
|
||||
if (value != 1)
|
||||
break;
|
||||
|
||||
Call::later([this]() { chooseSfzFile(); });
|
||||
break;
|
||||
|
||||
case kTagLoadScalaFile:
|
||||
if (value != 1)
|
||||
break;
|
||||
|
||||
Call::later([this]() { chooseScalaFile(); });
|
||||
break;
|
||||
|
||||
case kTagSetVolume:
|
||||
ctrl.uiSendValue(EditId::Volume, value);
|
||||
updateVolumeLabel(value);
|
||||
break;
|
||||
|
||||
case kTagSetNumVoices:
|
||||
ctrl.uiSendValue(EditId::Polyphony, value);
|
||||
updateNumVoicesLabel(static_cast<int>(value));
|
||||
break;
|
||||
|
||||
case kTagSetOversampling:
|
||||
ctrl.uiSendValue(EditId::Oversampling, static_cast<float>(1 << static_cast<int>(value)));
|
||||
updateOversamplingLabel(static_cast<int>(value));
|
||||
break;
|
||||
|
||||
case kTagSetPreloadSize:
|
||||
ctrl.uiSendValue(EditId::PreloadSize, value);
|
||||
updatePreloadSizeLabel(static_cast<int>(value));
|
||||
break;
|
||||
|
||||
case kTagSetScalaRootKey:
|
||||
ctrl.uiSendValue(EditId::ScalaRootKey, value);
|
||||
updateScalaRootKeyLabel(static_cast<int>(value));
|
||||
break;
|
||||
|
||||
case kTagSetTuningFrequency:
|
||||
ctrl.uiSendValue(EditId::TuningFrequency, value);
|
||||
updateTuningFrequencyLabel(value);
|
||||
break;
|
||||
|
||||
case kTagSetStretchedTuning:
|
||||
ctrl.uiSendValue(EditId::StretchTuning, value);
|
||||
updateStretchedTuningLabel(value);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (tag >= kTagFirstChangePanel && tag <= kTagLastChangePanel) {
|
||||
int panelId = tag - kTagFirstChangePanel;
|
||||
ctrl.uiSendValue(EditId::UIActivePanel, static_cast<float>(panelId));
|
||||
setActivePanel(panelId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::Impl::enterOrLeaveEdit(CControl* ctl, bool enter)
|
||||
{
|
||||
int32_t tag = ctl->getTag();
|
||||
EditId id;
|
||||
|
||||
switch (tag) {
|
||||
case kTagSetVolume: id = EditId::Volume; break;
|
||||
case kTagSetNumVoices: id = EditId::Polyphony; break;
|
||||
case kTagSetOversampling: id = EditId::Oversampling; break;
|
||||
case kTagSetPreloadSize: id = EditId::PreloadSize; break;
|
||||
case kTagSetScalaRootKey: id = EditId::ScalaRootKey; break;
|
||||
case kTagSetTuningFrequency: id = EditId::TuningFrequency; break;
|
||||
case kTagSetStretchedTuning: id = EditId::StretchTuning; break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
EditorController& ctrl = *ctrl_;
|
||||
if (enter)
|
||||
ctrl.uiBeginSend(id);
|
||||
else
|
||||
ctrl.uiEndSend(id);
|
||||
}
|
||||
|
||||
void Editor::Impl::controlBeginEdit(CControl* ctl)
|
||||
{
|
||||
enterOrLeaveEdit(ctl, true);
|
||||
}
|
||||
|
||||
void Editor::Impl::controlEndEdit(CControl* ctl)
|
||||
{
|
||||
enterOrLeaveEdit(ctl, false);
|
||||
}
|
||||
30
editor/src/editor/Editor.h
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
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);
|
||||
}
|
||||
|
|
@ -5,7 +5,10 @@
|
|||
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||
|
||||
#include "GUIComponents.h"
|
||||
|
||||
#include "utility/vstgui_before.h"
|
||||
#include "vstgui/lib/cdrawcontext.h"
|
||||
#include "utility/vstgui_after.h"
|
||||
|
||||
SimpleSlider::SimpleSlider(const CRect& bounds, IControlListener* listener, int32_t tag)
|
||||
: CSliderBase(bounds, listener, tag)
|
||||
|
|
@ -25,6 +28,8 @@ void SimpleSlider::draw(CDrawContext* dc)
|
|||
CRect bounds = getViewSize();
|
||||
CRect handle = calculateHandleRect(getValueNormalized());
|
||||
|
||||
dc->setDrawMode(kAntiAliasing);
|
||||
|
||||
dc->setFrameColor(_frame);
|
||||
dc->drawRect(bounds, kDrawStroked);
|
||||
|
||||
|
|
@ -5,8 +5,11 @@
|
|||
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "utility/vstgui_before.h"
|
||||
#include "vstgui/lib/controls/cslider.h"
|
||||
#include "vstgui/lib/ccolor.h"
|
||||
#include "utility/vstgui_after.h"
|
||||
|
||||
using namespace VSTGUI;
|
||||
|
||||
9
editor/src/editor/utility/vstgui_after.h
Normal file
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
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
|
||||
|
|
@ -11,6 +11,10 @@ set (LV2PLUGIN_TTL_SRC_FILES
|
|||
manifest.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
|
||||
${LV2PLUGIN_TTL_SRC_FILES}
|
||||
)
|
||||
|
|
@ -19,33 +23,63 @@ add_library (${LV2PLUGIN_PRJ_NAME} MODULE
|
|||
atomic_compat.h
|
||||
${LV2PLUGIN_TTL_SRC_FILES})
|
||||
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()
|
||||
# MacOS linker does not support this apparently https://bugs.webkit.org/show_bug.cgi?id=144555
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
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,-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()
|
||||
target_include_directories(${LV2PLUGIN_PRJ_NAME} PRIVATE . external/ardour)
|
||||
sfizz_enable_lto_if_needed (${LV2PLUGIN_PRJ_NAME})
|
||||
if (MINGW)
|
||||
set_target_properties (${LV2PLUGIN_PRJ_NAME} PROPERTIES LINK_FLAGS "-static")
|
||||
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
|
||||
# <build_dir>/lv2/<plugin_name>_lv2.<ext> to
|
||||
# <build_dir>/lv2/<plugin_name>.lv2/<plugin_name>.<ext>
|
||||
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 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,
|
||||
# create the destination directory if it doesn't exists and copy needed files
|
||||
file (MAKE_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||
configure_file (manifest.ttl.in ${PROJECT_BINARY_DIR}/manifest.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)
|
||||
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})
|
||||
endif()
|
||||
|
||||
|
|
@ -54,12 +88,22 @@ set(LV2_RESOURCES
|
|||
DefaultInstrument.sfz
|
||||
DefaultScale.scl)
|
||||
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})
|
||||
file (COPY "${CMAKE_CURRENT_SOURCE_DIR}/resources/${res}"
|
||||
DESTINATION "${PROJECT_BINARY_DIR}/Resources")
|
||||
DESTINATION "${PROJECT_BINARY_DIR}/Contents/Resources")
|
||||
endforeach()
|
||||
|
||||
# Copy editor resources
|
||||
if (SFIZZ_LV2_UI)
|
||||
execute_process (
|
||||
COMMAND "${CMAKE_COMMAND}" -E make_directory "${PROJECT_BINARY_DIR}/Contents/Resources")
|
||||
foreach(res ${EDITOR_RESOURCES})
|
||||
file (COPY "${CMAKE_CURRENT_SOURCE_DIR}/../editor/resources/${res}"
|
||||
DESTINATION "${PROJECT_BINARY_DIR}/Contents/Resources")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# Installation
|
||||
if (NOT MSVC)
|
||||
install (DIRECTORY ${PROJECT_BINARY_DIR} DESTINATION ${LV2PLUGIN_INSTALL_DIR}
|
||||
|
|
|
|||
4
lv2/lv2ui.version
Normal file
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 rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||
|
||||
<@LV2PLUGIN_URI@>
|
||||
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> .
|
||||
|
||||
@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> .
|
||||
|
|
|
|||
61
lv2/sfizz.c
61
lv2/sfizz.c
|
|
@ -32,6 +32,9 @@
|
|||
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/util.h>
|
||||
#include <lv2/buf-size/buf-size.h>
|
||||
|
|
@ -58,23 +61,11 @@
|
|||
|
||||
#include "atomic_compat.h"
|
||||
|
||||
#define SFIZZ_URI "http://sfztools.github.io/sfizz"
|
||||
#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"
|
||||
|
||||
#define CHANNEL_MASK 0x0F
|
||||
#define MIDI_CHANNEL(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 MAX_BLOCK_SIZE 8192
|
||||
#define MAX_PATH_SIZE 1024
|
||||
#define MAX_VOICES 256
|
||||
#define DEFAULT_VOICES 64
|
||||
#define DEFAULT_OVERSAMPLING SFIZZ_OVERSAMPLING_X1
|
||||
|
|
@ -82,8 +73,8 @@
|
|||
#define LOG_SAMPLE_COUNT 48000
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
#define DEFAULT_SCALA_FILE "Resources/DefaultScale.scl"
|
||||
#define DEFAULT_SFZ_FILE "Resources/DefaultInstrument.sfz"
|
||||
#define DEFAULT_SCALA_FILE "Contents/Resources/DefaultScale.scl"
|
||||
#define DEFAULT_SFZ_FILE "Contents/Resources/DefaultInstrument.sfz"
|
||||
// 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))
|
||||
|
||||
|
|
@ -115,6 +106,11 @@ typedef struct
|
|||
const float *tuning_frequency_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
|
||||
LV2_Atom_Forge forge; ///< Forge for writing atoms in run thread
|
||||
|
|
@ -187,23 +183,6 @@ typedef struct
|
|||
char bundle_path[MAX_BUNDLE_PATH_SIZE];
|
||||
} sfizz_plugin_t;
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SFIZZ_TIMEINFO_POSITION = 1 << 0,
|
||||
|
|
@ -369,6 +348,21 @@ connect_port(LV2_Handle instance,
|
|||
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:
|
||||
break;
|
||||
}
|
||||
|
|
@ -977,6 +971,11 @@ run(LV2_Handle instance, uint32_t sample_count)
|
|||
sfizz_lv2_check_oversampling(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
|
||||
self->sample_counter += (int)sample_count;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
||||
@prefix state: <http://lv2plug.in/ns/ext/state#> .
|
||||
@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 urid: <http://lv2plug.in/ns/ext/urid#> .
|
||||
@prefix work: <http://lv2plug.in/ns/ext/worker#> .
|
||||
|
|
@ -83,6 +84,8 @@ midnam:update a lv2:Feature .
|
|||
opts:supportedOption param:sampleRate ;
|
||||
opts:supportedOption bufsize:maxBlockLength, bufsize:nominalBlockLength ;
|
||||
|
||||
@LV2PLUGIN_IF_ENABLE_UI@ui:ui <@LV2PLUGIN_URI@#ui> ;
|
||||
|
||||
patch:writable <@LV2PLUGIN_URI@:sfzfile> ,
|
||||
<@LV2PLUGIN_URI@:tuningfile> ;
|
||||
|
||||
|
|
@ -310,4 +313,70 @@ midnam:update a lv2:Feature .
|
|||
lv2:default 0 ;
|
||||
lv2:minimum 0 ;
|
||||
lv2:maximum 256 ;
|
||||
] , [
|
||||
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
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,
|
||||
};
|
||||
497
lv2/sfizz_ui.cpp
Normal file
497
lv2/sfizz_ui.cpp
Normal file
|
|
@ -0,0 +1,497 @@
|
|||
/*
|
||||
SPDX-License-Identifier: ISC
|
||||
|
||||
Sfizz LV2 plugin
|
||||
|
||||
Copyright 2019-2020, Paul Ferrand <paul@ferrand.cc>
|
||||
|
||||
This file was based on skeleton and example code from the LV2 plugin
|
||||
distribution available at http://lv2plug.in/
|
||||
|
||||
The LV2 sample plugins have the following copyright and notice, which are
|
||||
extended to the current work:
|
||||
Copyright 2011-2016 David Robillard <d@drobilla.net>
|
||||
Copyright 2011 Gabriel M. Beddingfield <gabriel@teuton.org>
|
||||
Copyright 2011 James Morris <jwm.art.net@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
Compiling this plugin statically against libsndfile implies distributing it
|
||||
under the terms of the LGPL v3 license. See the LICENSE.md file for more
|
||||
information. If you did not receive a LICENSE.md file, inform the current
|
||||
maintainer.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "sfizz_lv2.h"
|
||||
|
||||
#include "editor/Editor.h"
|
||||
#include "editor/EditorController.h"
|
||||
#include "editor/EditIds.h"
|
||||
#include <lv2/ui/ui.h>
|
||||
#include <lv2/atom/atom.h>
|
||||
#include <lv2/atom/forge.h>
|
||||
#include <lv2/atom/util.h>
|
||||
#include <lv2/midi/midi.h>
|
||||
#include <lv2/patch/patch.h>
|
||||
#include <lv2/urid/urid.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
#include "vstgui_helpers.h"
|
||||
|
||||
#include "editor/utility/vstgui_before.h"
|
||||
#include "vstgui/lib/cframe.h"
|
||||
#include "vstgui/lib/platform/iplatformframe.h"
|
||||
#if defined(_WIN32)
|
||||
#include "vstgui/lib/platform/platform_win32.h"
|
||||
#endif
|
||||
#include "editor/utility/vstgui_after.h"
|
||||
using namespace VSTGUI;
|
||||
|
||||
///
|
||||
struct FrameHolderDeleter {
|
||||
void operator()(CFrame* frame) const
|
||||
{
|
||||
if (frame->getNbReference() != 1)
|
||||
frame->forget();
|
||||
else
|
||||
frame->close();
|
||||
}
|
||||
};
|
||||
typedef std::unique_ptr<CFrame, FrameHolderDeleter> FrameHolder;
|
||||
|
||||
///
|
||||
struct sfizz_ui_t : EditorController, VSTGUIEditorInterface {
|
||||
#if LINUX
|
||||
SoHandleInitializer soHandleInitializer;
|
||||
#endif
|
||||
#if MAC
|
||||
BundleRefInitializer bundleRefInitializer;
|
||||
#endif
|
||||
LV2UI_Write_Function write = nullptr;
|
||||
LV2UI_Controller con = nullptr;
|
||||
LV2_URID_Map *map = nullptr;
|
||||
LV2_URID_Unmap *unmap = nullptr;
|
||||
LV2UI_Resize *resize = nullptr;
|
||||
LV2UI_Touch *touch = nullptr;
|
||||
std::unique_ptr<Editor> editor;
|
||||
FrameHolder uiFrame;
|
||||
#if LINUX
|
||||
SharedPointer<Lv2IdleRunLoop> runLoop;
|
||||
#endif
|
||||
|
||||
/// VSTGUIEditorInterface
|
||||
CFrame* getFrame() const override { return uiFrame.get(); }
|
||||
|
||||
LV2_Atom_Forge atom_forge;
|
||||
LV2_URID atom_event_transfer_uri;
|
||||
LV2_URID atom_object_uri;
|
||||
LV2_URID atom_path_uri;
|
||||
LV2_URID atom_urid_uri;
|
||||
LV2_URID midi_event_uri;
|
||||
LV2_URID patch_get_uri;
|
||||
LV2_URID patch_set_uri;
|
||||
LV2_URID patch_property_uri;
|
||||
LV2_URID patch_value_uri;
|
||||
LV2_URID sfizz_sfz_file_uri;
|
||||
LV2_URID sfizz_scala_file_uri;
|
||||
|
||||
protected:
|
||||
void uiSendValue(EditId id, const EditValue& v) override;
|
||||
void uiBeginSend(EditId id) override;
|
||||
void uiEndSend(EditId id) override;
|
||||
void uiSendMIDI(const uint8_t* msg, uint32_t len) override;
|
||||
|
||||
private:
|
||||
void uiTouch(EditId id, bool t);
|
||||
};
|
||||
|
||||
static LV2UI_Handle
|
||||
instantiate(const LV2UI_Descriptor *descriptor,
|
||||
const char *plugin_uri,
|
||||
const char *bundle_path,
|
||||
LV2UI_Write_Function write_function,
|
||||
LV2UI_Controller controller,
|
||||
LV2UI_Widget *widget,
|
||||
const LV2_Feature * const *features)
|
||||
{
|
||||
std::unique_ptr<sfizz_ui_t> self { new sfizz_ui_t };
|
||||
|
||||
(void)descriptor;
|
||||
(void)plugin_uri;
|
||||
(void)bundle_path;
|
||||
|
||||
self->write = write_function;
|
||||
self->con = controller;
|
||||
|
||||
void *parentWindowId = nullptr;
|
||||
|
||||
LV2_URID_Map *map = nullptr;
|
||||
LV2_URID_Unmap *unmap = nullptr;
|
||||
|
||||
for (const LV2_Feature *const *f = features; *f; f++)
|
||||
{
|
||||
if (!strcmp((**f).URI, LV2_URID__map))
|
||||
self->map = map = (LV2_URID_Map *)(**f).data;
|
||||
else if (!strcmp((**f).URI, LV2_URID__unmap))
|
||||
self->unmap = unmap = (LV2_URID_Unmap *)(**f).data;
|
||||
else if (!strcmp((**f).URI, LV2_UI__resize))
|
||||
self->resize = (LV2UI_Resize *)(**f).data;
|
||||
else if (!strcmp((**f).URI, LV2_UI__touch))
|
||||
self->touch = (LV2UI_Touch*)(**f).data;
|
||||
else if (!strcmp((**f).URI, LV2_UI__parent))
|
||||
parentWindowId = (**f).data;
|
||||
}
|
||||
|
||||
// The map feature is required
|
||||
if (!map || !unmap)
|
||||
return nullptr;
|
||||
|
||||
LV2_Atom_Forge *forge = &self->atom_forge;
|
||||
lv2_atom_forge_init(forge, map);
|
||||
self->atom_event_transfer_uri = map->map(map->handle, LV2_ATOM__eventTransfer);
|
||||
self->atom_object_uri = map->map(map->handle, LV2_ATOM__Object);
|
||||
self->atom_path_uri = map->map(map->handle, LV2_ATOM__Path);
|
||||
self->atom_urid_uri = map->map(map->handle, LV2_ATOM__URID);
|
||||
self->midi_event_uri = map->map(map->handle, LV2_MIDI__MidiEvent);
|
||||
self->patch_get_uri = map->map(map->handle, LV2_PATCH__Get);
|
||||
self->patch_set_uri = map->map(map->handle, LV2_PATCH__Set);
|
||||
self->patch_property_uri = map->map(map->handle, LV2_PATCH__property);
|
||||
self->patch_value_uri = map->map(map->handle, LV2_PATCH__value);
|
||||
self->sfizz_sfz_file_uri = map->map(map->handle, SFIZZ__sfzFile);
|
||||
self->sfizz_scala_file_uri = map->map(map->handle, SFIZZ__tuningfile);
|
||||
|
||||
// set up the resource path
|
||||
// * on Linux, this is determined by going 2 folders back from the SO path
|
||||
// name, and appending "Contents/Resources" (not overridable)
|
||||
// * on Windows, the folder is set programmatically
|
||||
// * on macOS, resource files are looked up using CFBundle APIs
|
||||
#if defined(_WIN32)
|
||||
IWin32PlatformFrame::setResourceBasePath((std::string(bundle_path) + "\\Contents\\Resources\\").c_str());
|
||||
#endif
|
||||
|
||||
// makes labels refresh correctly
|
||||
CView::kDirtyCallAlwaysOnMainThread = true;
|
||||
|
||||
const CRect uiBounds(0, 0, Editor::viewWidth, Editor::viewHeight);
|
||||
CFrame* uiFrame = new CFrame(uiBounds, self.get());
|
||||
self->uiFrame.reset(uiFrame);
|
||||
|
||||
IPlatformFrameConfig* config = nullptr;
|
||||
#if LINUX
|
||||
SharedPointer<Lv2IdleRunLoop> runLoop = new Lv2IdleRunLoop;
|
||||
self->runLoop = runLoop;
|
||||
VSTGUI::X11::FrameConfig x11Config;
|
||||
x11Config.runLoop = runLoop;
|
||||
config = &x11Config;
|
||||
#endif
|
||||
|
||||
if (!uiFrame->open(parentWindowId, kDefaultNative, config))
|
||||
return nullptr;
|
||||
|
||||
Editor *editor = new Editor(*self);
|
||||
self->editor.reset(editor);
|
||||
editor->open(*uiFrame);
|
||||
|
||||
*widget = reinterpret_cast<LV2UI_Widget>(uiFrame->getPlatformFrame()->getPlatformRepresentation());
|
||||
|
||||
if (self->resize)
|
||||
self->resize->ui_resize(self->resize->handle, Editor::viewWidth, Editor::viewHeight);
|
||||
|
||||
// send a request to receive all parameters
|
||||
uint8_t buffer[256];
|
||||
lv2_atom_forge_set_buffer(forge, buffer, sizeof(buffer));
|
||||
LV2_Atom_Forge_Frame frame;
|
||||
LV2_Atom *msg = (LV2_Atom *)lv2_atom_forge_object(forge, &frame, 0, self->patch_get_uri);
|
||||
lv2_atom_forge_pop(forge, &frame);
|
||||
write_function(controller, 0, lv2_atom_total_size(msg), self->atom_event_transfer_uri, msg);
|
||||
|
||||
return self.release();
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup(LV2UI_Handle ui)
|
||||
{
|
||||
sfizz_ui_t *self = (sfizz_ui_t *)ui;
|
||||
delete self;
|
||||
}
|
||||
|
||||
static void
|
||||
port_event(LV2UI_Handle ui,
|
||||
uint32_t port_index,
|
||||
uint32_t buffer_size,
|
||||
uint32_t format,
|
||||
const void *buffer)
|
||||
{
|
||||
sfizz_ui_t *self = (sfizz_ui_t *)ui;
|
||||
|
||||
if (format == 0) {
|
||||
const float v = *reinterpret_cast<const float*>(buffer);
|
||||
|
||||
switch (port_index) {
|
||||
case SFIZZ_VOLUME:
|
||||
self->uiReceiveValue(EditId::Volume, v);
|
||||
break;
|
||||
case SFIZZ_POLYPHONY:
|
||||
self->uiReceiveValue(EditId::Polyphony, v);
|
||||
break;
|
||||
case SFIZZ_OVERSAMPLING:
|
||||
self->uiReceiveValue(EditId::Oversampling, v);
|
||||
break;
|
||||
case SFIZZ_PRELOAD:
|
||||
self->uiReceiveValue(EditId::PreloadSize, v);
|
||||
break;
|
||||
case SFIZZ_SCALA_ROOT_KEY:
|
||||
self->uiReceiveValue(EditId::ScalaRootKey, v);
|
||||
break;
|
||||
case SFIZZ_TUNING_FREQUENCY:
|
||||
self->uiReceiveValue(EditId::TuningFrequency, v);
|
||||
break;
|
||||
case SFIZZ_STRETCH_TUNING:
|
||||
self->uiReceiveValue(EditId::StretchTuning, v);
|
||||
break;
|
||||
case SFIZZ_ACTIVE_VOICES:
|
||||
self->uiReceiveValue(EditId::UINumActiveVoices, v);
|
||||
break;
|
||||
case SFIZZ_NUM_CURVES:
|
||||
self->uiReceiveValue(EditId::UINumCurves, v);
|
||||
break;
|
||||
case SFIZZ_NUM_MASTERS:
|
||||
self->uiReceiveValue(EditId::UINumMasters, v);
|
||||
break;
|
||||
case SFIZZ_NUM_GROUPS:
|
||||
self->uiReceiveValue(EditId::UINumGroups, v);
|
||||
break;
|
||||
case SFIZZ_NUM_REGIONS:
|
||||
self->uiReceiveValue(EditId::UINumRegions, v);
|
||||
break;
|
||||
case SFIZZ_NUM_SAMPLES:
|
||||
self->uiReceiveValue(EditId::UINumPreloadedSamples, v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (format == self->atom_event_transfer_uri) {
|
||||
auto *atom = reinterpret_cast<const LV2_Atom *>(buffer);
|
||||
|
||||
if (atom->type == self->atom_object_uri) {
|
||||
const LV2_Atom *prop = nullptr;
|
||||
const LV2_Atom *value = nullptr;
|
||||
|
||||
lv2_atom_object_get(
|
||||
reinterpret_cast<const LV2_Atom_Object *>(atom),
|
||||
self->patch_property_uri, &prop, self->patch_value_uri, &value, 0);
|
||||
|
||||
if (prop && value && prop->type == self->atom_urid_uri) {
|
||||
const LV2_URID prop_uri = reinterpret_cast<const LV2_Atom_URID *>(prop)->body;
|
||||
auto *value_body = reinterpret_cast<const char *>(LV2_ATOM_BODY_CONST(value));
|
||||
|
||||
if (prop_uri == self->sfizz_sfz_file_uri && value->type == self->atom_path_uri) {
|
||||
std::string path(value_body, strnlen(value_body, value->size));
|
||||
self->uiReceiveValue(EditId::SfzFile, path);
|
||||
}
|
||||
else if (prop_uri == self->sfizz_scala_file_uri && value->type == self->atom_path_uri) {
|
||||
std::string path(value_body, strnlen(value_body, value->size));
|
||||
self->uiReceiveValue(EditId::ScalaFile, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(void)buffer_size;
|
||||
}
|
||||
|
||||
static int
|
||||
idle(LV2UI_Handle ui)
|
||||
{
|
||||
sfizz_ui_t *self = (sfizz_ui_t *)ui;
|
||||
|
||||
#if LINUX
|
||||
self->runLoop->execIdle();
|
||||
#else
|
||||
(void)self;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const LV2UI_Idle_Interface idle_interface = {
|
||||
&idle,
|
||||
};
|
||||
|
||||
static int
|
||||
show(LV2UI_Handle ui)
|
||||
{
|
||||
sfizz_ui_t *self = (sfizz_ui_t *)ui;
|
||||
self->uiFrame->setVisible(true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
hide(LV2UI_Handle ui)
|
||||
{
|
||||
sfizz_ui_t *self = (sfizz_ui_t *)ui;
|
||||
self->uiFrame->setVisible(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const LV2UI_Show_Interface show_interface = {
|
||||
&show,
|
||||
&hide,
|
||||
};
|
||||
|
||||
const void *
|
||||
extension_data(const char *uri)
|
||||
{
|
||||
if (!strcmp(uri, LV2_UI__idleInterface))
|
||||
return &idle_interface;
|
||||
|
||||
if (!strcmp(uri, LV2_UI__showInterface))
|
||||
return &show_interface;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static const LV2UI_Descriptor descriptor = {
|
||||
SFIZZ_UI_URI,
|
||||
instantiate,
|
||||
cleanup,
|
||||
port_event,
|
||||
extension_data,
|
||||
};
|
||||
|
||||
LV2_SYMBOL_EXPORT
|
||||
const LV2UI_Descriptor *
|
||||
lv2ui_descriptor(uint32_t index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return &descriptor;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
void sfizz_ui_t::uiSendValue(EditId id, const EditValue& v)
|
||||
{
|
||||
auto sendFloat = [this](int port, float value) {
|
||||
write(con, port, sizeof(float), 0, &value);
|
||||
};
|
||||
|
||||
auto sendPath = [this](LV2_URID property, const std::string& value) {
|
||||
LV2_Atom_Forge *forge = &atom_forge;
|
||||
LV2_Atom_Forge_Frame frame;
|
||||
alignas(LV2_Atom) uint8_t buffer[MAX_PATH_SIZE + 512];
|
||||
auto *atom = reinterpret_cast<const LV2_Atom *>(buffer);
|
||||
lv2_atom_forge_set_buffer(forge, (uint8_t *)&buffer, sizeof(buffer));
|
||||
if (lv2_atom_forge_object(forge, &frame, 0, patch_set_uri) &&
|
||||
lv2_atom_forge_key(forge, patch_property_uri) &&
|
||||
lv2_atom_forge_urid(forge, property) &&
|
||||
lv2_atom_forge_key(forge, patch_value_uri) &&
|
||||
lv2_atom_forge_path(forge, value.data(), value.size()))
|
||||
{
|
||||
lv2_atom_forge_pop(forge, &frame);
|
||||
write(con, SFIZZ_CONTROL, lv2_atom_total_size(atom), atom_event_transfer_uri, atom);
|
||||
}
|
||||
};
|
||||
|
||||
switch (id) {
|
||||
case EditId::Volume:
|
||||
sendFloat(SFIZZ_VOLUME, v.to_float());
|
||||
break;
|
||||
case EditId::Polyphony:
|
||||
sendFloat(SFIZZ_POLYPHONY, v.to_float());
|
||||
break;
|
||||
case EditId::Oversampling:
|
||||
sendFloat(SFIZZ_OVERSAMPLING, v.to_float());
|
||||
break;
|
||||
case EditId::PreloadSize:
|
||||
sendFloat(SFIZZ_PRELOAD, v.to_float());
|
||||
break;
|
||||
case EditId::ScalaRootKey:
|
||||
sendFloat(SFIZZ_SCALA_ROOT_KEY, v.to_float());
|
||||
break;
|
||||
case EditId::TuningFrequency:
|
||||
sendFloat(SFIZZ_TUNING_FREQUENCY, v.to_float());
|
||||
break;
|
||||
case EditId::StretchTuning:
|
||||
sendFloat(SFIZZ_STRETCH_TUNING, v.to_float());
|
||||
break;
|
||||
case EditId::SfzFile:
|
||||
sendPath(sfizz_sfz_file_uri, v.to_string());
|
||||
break;
|
||||
case EditId::ScalaFile:
|
||||
sendPath(sfizz_scala_file_uri, v.to_string());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void sfizz_ui_t::uiBeginSend(EditId id)
|
||||
{
|
||||
uiTouch(id, true);
|
||||
}
|
||||
|
||||
void sfizz_ui_t::uiEndSend(EditId id)
|
||||
{
|
||||
uiTouch(id, false);
|
||||
}
|
||||
|
||||
void sfizz_ui_t::uiTouch(EditId id, bool t)
|
||||
{
|
||||
if (!touch)
|
||||
return;
|
||||
|
||||
switch (id) {
|
||||
case EditId::Volume:
|
||||
touch->touch(touch->handle, SFIZZ_VOLUME, t);
|
||||
break;
|
||||
case EditId::Polyphony:
|
||||
touch->touch(touch->handle, SFIZZ_POLYPHONY, t);
|
||||
break;
|
||||
case EditId::Oversampling:
|
||||
touch->touch(touch->handle, SFIZZ_OVERSAMPLING, t);
|
||||
break;
|
||||
case EditId::PreloadSize:
|
||||
touch->touch(touch->handle, SFIZZ_PRELOAD, t);
|
||||
break;
|
||||
case EditId::ScalaRootKey:
|
||||
touch->touch(touch->handle, SFIZZ_SCALA_ROOT_KEY, t);
|
||||
break;
|
||||
case EditId::TuningFrequency:
|
||||
touch->touch(touch->handle, SFIZZ_TUNING_FREQUENCY, t);
|
||||
break;
|
||||
case EditId::StretchTuning:
|
||||
touch->touch(touch->handle, SFIZZ_STRETCH_TUNING, t);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void sfizz_ui_t::uiSendMIDI(const uint8_t* msg, uint32_t len)
|
||||
{
|
||||
LV2_Atom_Forge *forge = &atom_forge;
|
||||
alignas(LV2_Atom) uint8_t buffer[512];
|
||||
auto *atom = reinterpret_cast<const LV2_Atom *>(buffer);
|
||||
lv2_atom_forge_set_buffer(forge, (uint8_t *)&buffer, sizeof(buffer));
|
||||
if (lv2_atom_forge_atom(forge, len, midi_event_uri) &&
|
||||
lv2_atom_forge_write(forge, msg, len))
|
||||
{
|
||||
write(con, SFIZZ_CONTROL, lv2_atom_total_size(atom), atom_event_transfer_uri, atom);
|
||||
}
|
||||
}
|
||||
14
lv2/sfizz_ui.ttl.in
Normal file
14
lv2/sfizz_ui.ttl.in
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||
@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
|
||||
|
||||
<@LV2PLUGIN_URI@#ui>
|
||||
lv2:extensionData ui:idleInterface ;
|
||||
lv2:extensionData ui:showInterface ;
|
||||
lv2:requiredFeature ui:idleInterface ;
|
||||
lv2:optionalFeature ui:noUserResize ;
|
||||
lv2:optionalFeature ui:resize ;
|
||||
lv2:optionalFeature ui:parent ;
|
||||
lv2:optionalFeature ui:touch ;
|
||||
lv2:requiredFeature urid:map ;
|
||||
lv2:requiredFeature urid:unmap .
|
||||
216
lv2/vstgui_helpers.cpp
Normal file
216
lv2/vstgui_helpers.cpp
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
// 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
|
||||
|
||||
// Note(jpc) same code as used in Surge LV2, I am the original author
|
||||
|
||||
#include "vstgui_helpers.h"
|
||||
#include <lv2/ui/ui.h>
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <stdexcept>
|
||||
#if LINUX
|
||||
#include <dlfcn.h>
|
||||
#include <poll.h>
|
||||
#endif
|
||||
#if WINDOWS
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#if MAC
|
||||
#include "vstgui/plugin-bindings/getpluginbundle.h"
|
||||
#endif
|
||||
|
||||
#if LINUX
|
||||
void Lv2IdleRunLoop::execIdle()
|
||||
{
|
||||
std::chrono::steady_clock::time_point tick = std::chrono::steady_clock::now();
|
||||
|
||||
for (Event& ev : _events)
|
||||
{
|
||||
if (!ev.alive)
|
||||
continue;
|
||||
|
||||
// TODO LV2: fix me, XCB descriptor polling not working at this point
|
||||
#if 0
|
||||
pollfd pfd = {};
|
||||
pfd.fd = ev.fd;
|
||||
pfd.events = POLLIN|POLLERR|POLLHUP;
|
||||
if (poll(&pfd, 1, 0) > 0)
|
||||
#endif
|
||||
{
|
||||
ev.handler->onEvent();
|
||||
}
|
||||
}
|
||||
|
||||
for (Timer& tm : _timers)
|
||||
{
|
||||
if (!tm.alive)
|
||||
continue;
|
||||
|
||||
if (tm.lastTickValid)
|
||||
{
|
||||
std::chrono::steady_clock::duration duration = tick - tm.lastTick;
|
||||
tm.counter += std::chrono::duration_cast<std::chrono::microseconds>(duration);
|
||||
if (tm.counter >= tm.interval)
|
||||
{
|
||||
tm.handler->onTimer();
|
||||
tm.counter = std::min(tm.counter - tm.interval, tm.interval);
|
||||
}
|
||||
}
|
||||
tm.lastTick = tick;
|
||||
tm.lastTickValid = true;
|
||||
}
|
||||
|
||||
garbageCollectDeadHandlers<Event>(_events);
|
||||
garbageCollectDeadHandlers<Timer>(_timers);
|
||||
}
|
||||
|
||||
bool Lv2IdleRunLoop::registerEventHandler(int fd, VSTGUI::X11::IEventHandler* handler)
|
||||
{
|
||||
// fprintf(stderr, "registerEventHandler %d %p\n", fd, handler);
|
||||
|
||||
Event ev;
|
||||
ev.fd = fd;
|
||||
ev.handler = handler;
|
||||
ev.alive = true;
|
||||
_events.push_back(ev);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Lv2IdleRunLoop::unregisterEventHandler(VSTGUI::X11::IEventHandler* handler)
|
||||
{
|
||||
// fprintf(stderr, "unregisterEventHandler %p\n", handler);
|
||||
|
||||
auto it = std::find_if(_events.begin(), _events.end(), [handler](const Event& ev) -> bool {
|
||||
return ev.handler == handler && ev.alive;
|
||||
});
|
||||
|
||||
if (it != _events.end())
|
||||
it->alive = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Lv2IdleRunLoop::registerTimer(uint64_t interval, VSTGUI::X11::ITimerHandler* handler)
|
||||
{
|
||||
// fprintf(stderr, "registerTimer %lu %p\n", interval, handler);
|
||||
|
||||
Timer tm;
|
||||
tm.interval = std::chrono::milliseconds(interval);
|
||||
tm.counter = std::chrono::microseconds(0);
|
||||
tm.lastTickValid = false;
|
||||
tm.handler = handler;
|
||||
tm.alive = true;
|
||||
_timers.push_back(tm);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Lv2IdleRunLoop::unregisterTimer(VSTGUI::X11::ITimerHandler* handler)
|
||||
{
|
||||
// fprintf(stderr, "unregisterTimer %p\n", handler);
|
||||
|
||||
auto it = std::find_if(_timers.begin(), _timers.end(), [handler](const Timer& tm) -> bool {
|
||||
return tm.handler == handler && tm.alive;
|
||||
});
|
||||
|
||||
if (it != _timers.end())
|
||||
it->alive = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T> void Lv2IdleRunLoop::garbageCollectDeadHandlers(std::list<T>& handlers)
|
||||
{
|
||||
auto pos = handlers.begin();
|
||||
auto end = handlers.end();
|
||||
|
||||
while (pos != end)
|
||||
{
|
||||
auto curPos = pos++;
|
||||
if (!curPos->alive)
|
||||
handlers.erase(curPos);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
///
|
||||
#if LINUX
|
||||
namespace VSTGUI
|
||||
{
|
||||
void* soHandle = nullptr;
|
||||
|
||||
static volatile size_t soHandleCount = 0;
|
||||
static std::mutex soHandleMutex;
|
||||
|
||||
SoHandleInitializer::SoHandleInitializer()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(soHandleMutex);
|
||||
if (soHandleCount++ == 0) {
|
||||
Dl_info info;
|
||||
if (dladdr((void*)&lv2ui_descriptor, &info))
|
||||
soHandle = dlopen(info.dli_fname, RTLD_LAZY);
|
||||
if (!soHandle)
|
||||
throw std::runtime_error("SoHandleInitializer");
|
||||
}
|
||||
}
|
||||
|
||||
SoHandleInitializer::~SoHandleInitializer()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(soHandleMutex);
|
||||
if (--soHandleCount == 0) {
|
||||
dlclose(soHandle);
|
||||
soHandle = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace VSTGUI
|
||||
#endif
|
||||
|
||||
///
|
||||
#if WINDOWS
|
||||
void* hInstance = nullptr;
|
||||
|
||||
__declspec(dllexport)
|
||||
BOOL WINAPI DllMain(HINSTANCE dllInstance, DWORD reason, LPVOID)
|
||||
{
|
||||
if (reason == DLL_PROCESS_ATTACH)
|
||||
hInstance = dllInstance;
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
///
|
||||
#if MAC
|
||||
namespace VSTGUI
|
||||
{
|
||||
void* gBundleRef = nullptr;
|
||||
|
||||
static volatile size_t gBundleRefCount = 0;
|
||||
static std::mutex gBundleRefMutex;
|
||||
|
||||
BundleRefInitializer::BundleRefInitializer()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(gBundleRefMutex);
|
||||
if (gBundleRefCount++ == 0) {
|
||||
gBundleRef = GetPluginBundle();
|
||||
if (!gBundleRef)
|
||||
throw std::runtime_error("BundleRefInitializer");
|
||||
}
|
||||
}
|
||||
|
||||
BundleRefInitializer::~BundleRefInitializer()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(gBundleRefMutex);
|
||||
if (--gBundleRefCount == 0) {
|
||||
CFRelease((CFBundleRef)gBundleRef);
|
||||
gBundleRef = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace VSTGUI
|
||||
#endif
|
||||
89
lv2/vstgui_helpers.h
Normal file
89
lv2/vstgui_helpers.h
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
// 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
|
||||
|
||||
// Note(jpc) same code as used in Surge LV2, I am the original author
|
||||
|
||||
#pragma once
|
||||
#include <list>
|
||||
#include <chrono>
|
||||
|
||||
#include "editor/utility/vstgui_before.h"
|
||||
#include "vstgui/lib/vstguibase.h"
|
||||
#if LINUX
|
||||
#include "vstgui/lib/platform/platform_x11.h"
|
||||
#include "vstgui/lib/platform/linux/x11platform.h"
|
||||
#endif
|
||||
#include "editor/utility/vstgui_after.h"
|
||||
|
||||
#if LINUX
|
||||
class Lv2IdleRunLoop : public VSTGUI::X11::IRunLoop
|
||||
{
|
||||
public:
|
||||
void execIdle();
|
||||
|
||||
bool registerEventHandler(int fd, VSTGUI::X11::IEventHandler* handler) override;
|
||||
bool unregisterEventHandler(VSTGUI::X11::IEventHandler* handler) override;
|
||||
bool registerTimer(uint64_t interval, VSTGUI::X11::ITimerHandler* handler) override;
|
||||
bool unregisterTimer(VSTGUI::X11::ITimerHandler* handler) override;
|
||||
|
||||
void forget() override
|
||||
{}
|
||||
void remember() override
|
||||
{}
|
||||
|
||||
private:
|
||||
struct Event
|
||||
{
|
||||
int fd;
|
||||
VSTGUI::X11::IEventHandler* handler;
|
||||
bool alive;
|
||||
};
|
||||
struct Timer
|
||||
{
|
||||
std::chrono::microseconds interval;
|
||||
std::chrono::microseconds counter;
|
||||
bool lastTickValid;
|
||||
std::chrono::steady_clock::time_point lastTick;
|
||||
VSTGUI::X11::ITimerHandler* handler;
|
||||
bool alive;
|
||||
};
|
||||
|
||||
private:
|
||||
template <class T> static void garbageCollectDeadHandlers(std::list<T>& handlers);
|
||||
|
||||
private:
|
||||
std::list<Event> _events;
|
||||
std::list<Timer> _timers;
|
||||
};
|
||||
#endif
|
||||
|
||||
#if LINUX
|
||||
namespace VSTGUI
|
||||
{
|
||||
class SoHandleInitializer {
|
||||
public:
|
||||
SoHandleInitializer();
|
||||
~SoHandleInitializer();
|
||||
private:
|
||||
SoHandleInitializer(const SoHandleInitializer&) = delete;
|
||||
SoHandleInitializer& operator=(const SoHandleInitializer&) = delete;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MAC
|
||||
namespace VSTGUI
|
||||
{
|
||||
class BundleRefInitializer {
|
||||
public:
|
||||
BundleRefInitializer();
|
||||
~BundleRefInitializer();
|
||||
private:
|
||||
BundleRefInitializer(const BundleRefInitializer&) = delete;
|
||||
BundleRefInitializer& operator=(const BundleRefInitializer&) = delete;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
@ -48,9 +48,14 @@ Name: "lv2"; Description: "LV2 plugin"; Types: full custom;
|
|||
Name: "vst3"; Description: "VST3 plugin"; Types: full custom;
|
||||
|
||||
[Files]
|
||||
Source: "sfizz.lv2\sfizz.dll"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2"; Flags: ignoreversion
|
||||
Source: "sfizz.lv2\Contents\Binary\sfizz.dll"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2\Contents\Binary"; Flags: ignoreversion
|
||||
Source: "sfizz.lv2\Contents\Binary\sfizz_ui.dll"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2\Contents\Binary"; Flags: ignoreversion
|
||||
Source: "sfizz.lv2\Contents\Resources\DefaultInstrument.sfz"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2\Contents\Resources"
|
||||
Source: "sfizz.lv2\Contents\Resources\DefaultScale.scl"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2\Contents\Resources"
|
||||
Source: "sfizz.lv2\Contents\Resources\logo.png"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2\Contents\Resources"
|
||||
Source: "sfizz.lv2\manifest.ttl"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2"
|
||||
Source: "sfizz.lv2\sfizz.ttl"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2"
|
||||
Source: "sfizz.lv2\sfizz_ui.ttl"; Components: lv2; DestDir: "{commoncf}\LV2\sfizz.lv2"
|
||||
Source: "sfizz.lv2\lgpl-3.0.txt"; Components: main; DestDir: "{app}"
|
||||
Source: "sfizz.lv2\LICENSE.md"; Components: main; DestDir: "{app}"
|
||||
Source: "sfizz.vst3\desktop.ini"; Components: vst3; DestDir: "{commoncf}\VST3\sfizz.vst3"
|
||||
|
|
|
|||
|
|
@ -33,4 +33,5 @@ clang-tidy \
|
|||
-- -Iexternal/abseil-cpp -Isrc/external -Isrc/external/pugixml/src \
|
||||
-Isrc/sfizz -Isrc -Isrc/external/spline -Isrc/external/cpuid/src \
|
||||
-Ivst -Ivst/external/VST_SDK/VST3_SDK -Ivst/external/VST_SDK/VST3_SDK/vstgui4 -Ivst/external/ring_buffer \
|
||||
-Ieditor/src \
|
||||
-DNDEBUG -std=c++17
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ set(VSTPLUGIN_SOURCES
|
|||
SfizzVstController.cpp
|
||||
SfizzVstEditor.cpp
|
||||
SfizzVstState.cpp
|
||||
GUIComponents.cpp
|
||||
VstPluginFactory.cpp
|
||||
X11RunLoop.cpp)
|
||||
|
||||
|
|
@ -26,12 +25,8 @@ set(VSTPLUGIN_HEADERS
|
|||
SfizzVstController.h
|
||||
SfizzVstEditor.h
|
||||
SfizzVstState.h
|
||||
GUIComponents.h
|
||||
X11RunLoop.h)
|
||||
|
||||
set(VSTPLUGIN_RESOURCES
|
||||
logo.png)
|
||||
|
||||
add_library(${VSTPLUGIN_PRJ_NAME} MODULE
|
||||
${VSTPLUGIN_HEADERS}
|
||||
${VSTPLUGIN_SOURCES})
|
||||
|
|
@ -40,7 +35,8 @@ if(WIN32)
|
|||
target_sources(${VSTPLUGIN_PRJ_NAME} PRIVATE vst3.def)
|
||||
endif()
|
||||
target_link_libraries(${VSTPLUGIN_PRJ_NAME}
|
||||
PRIVATE ${PROJECT_NAME}::${PROJECT_NAME})
|
||||
PRIVATE ${PROJECT_NAME}::${PROJECT_NAME}
|
||||
PRIVATE sfizz_editor)
|
||||
target_include_directories(${VSTPLUGIN_PRJ_NAME}
|
||||
PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
set_target_properties(${VSTPLUGIN_PRJ_NAME} PROPERTIES
|
||||
|
|
@ -72,26 +68,21 @@ endif()
|
|||
# Create the bundle (see "VST 3 Locations / Format")
|
||||
execute_process (
|
||||
COMMAND "${CMAKE_COMMAND}" -E make_directory "${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/Resources")
|
||||
foreach(res ${VSTPLUGIN_RESOURCES})
|
||||
file (COPY "${CMAKE_CURRENT_SOURCE_DIR}/resources/${res}"
|
||||
foreach(res ${EDITOR_RESOURCES})
|
||||
file (COPY "${CMAKE_CURRENT_SOURCE_DIR}/../editor/resources/${res}"
|
||||
DESTINATION "${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/Resources")
|
||||
endforeach()
|
||||
if(WIN32)
|
||||
set_target_properties(${VSTPLUGIN_PRJ_NAME} PROPERTIES
|
||||
SUFFIX ".vst3"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/${VST3_PACKAGE_ARCHITECTURE}-win")
|
||||
foreach(config ${CMAKE_CONFIGURATION_TYPES})
|
||||
string(TOUPPER "${config}" config)
|
||||
set_target_properties(${VSTPLUGIN_PRJ_NAME} PROPERTIES
|
||||
"LIBRARY_OUTPUT_DIRECTORY_${config}" "${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/${VST3_PACKAGE_ARCHITECTURE}-win")
|
||||
endforeach()
|
||||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/${VST3_PACKAGE_ARCHITECTURE}-win/$<0:>")
|
||||
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/win/Plugin.ico"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/win/desktop.ini"
|
||||
DESTINATION "${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}")
|
||||
elseif(APPLE)
|
||||
set_target_properties(${VSTPLUGIN_PRJ_NAME} PROPERTIES
|
||||
SUFFIX ""
|
||||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/MacOS")
|
||||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/MacOS/$<0:>")
|
||||
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/mac/PkgInfo"
|
||||
DESTINATION "${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents")
|
||||
set(SFIZZ_VST3_BUNDLE_EXECUTABLE "${PROJECT_NAME}")
|
||||
|
|
@ -102,7 +93,7 @@ elseif(APPLE)
|
|||
DESTINATION "${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/Resources")
|
||||
else()
|
||||
set_target_properties(${VSTPLUGIN_PRJ_NAME} PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/${VST3_PACKAGE_ARCHITECTURE}-linux")
|
||||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/${VST3_PACKAGE_ARCHITECTURE}-linux/$<0:>")
|
||||
endif()
|
||||
|
||||
file(COPY "gpl-3.0.txt"
|
||||
|
|
@ -237,7 +228,7 @@ elseif(SFIZZ_AU)
|
|||
COMMAND "${CMAKE_COMMAND}" -E make_directory "${PROJECT_BINARY_DIR}/${AUPLUGIN_BUNDLE_NAME}/Contents/Resources")
|
||||
set_target_properties(${AUPLUGIN_PRJ_NAME} PROPERTIES
|
||||
SUFFIX ""
|
||||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${AUPLUGIN_BUNDLE_NAME}/Contents/MacOS")
|
||||
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${AUPLUGIN_BUNDLE_NAME}/Contents/MacOS/$<0:>")
|
||||
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/mac/PkgInfo"
|
||||
DESTINATION "${PROJECT_BINARY_DIR}/${AUPLUGIN_BUNDLE_NAME}/Contents")
|
||||
set(SFIZZ_AU_BUNDLE_EXECUTABLE "${PROJECT_NAME}")
|
||||
|
|
|
|||
|
|
@ -35,15 +35,15 @@ tresult PLUGIN_API SfizzVstControllerNoUi::initialize(FUnknown* context)
|
|||
Steinberg::String("Preload size"), pid++, nullptr,
|
||||
0, Vst::ParameterInfo::kCanAutomate, Vst::kRootUnitId));
|
||||
parameters.addParameter(
|
||||
kParamScalaRootKey.createParameter(
|
||||
kParamScalaRootKeyRange.createParameter(
|
||||
Steinberg::String("Scala root key"), pid++, nullptr,
|
||||
0, Vst::ParameterInfo::kCanAutomate, Vst::kRootUnitId));
|
||||
parameters.addParameter(
|
||||
kParamTuningFrequency.createParameter(
|
||||
kParamTuningFrequencyRange.createParameter(
|
||||
Steinberg::String("Tuning frequency"), pid++, Steinberg::String("Hz"),
|
||||
0, Vst::ParameterInfo::kCanAutomate, Vst::kRootUnitId));
|
||||
parameters.addParameter(
|
||||
kParamStretchedTuning.createParameter(
|
||||
kParamStretchedTuningRange.createParameter(
|
||||
Steinberg::String("Stretched tuning"), pid++, nullptr,
|
||||
0, Vst::ParameterInfo::kCanAutomate, Vst::kRootUnitId));
|
||||
|
||||
|
|
@ -175,17 +175,17 @@ tresult PLUGIN_API SfizzVstController::setParamNormalized(Vst::ParamID tag, Vst:
|
|||
}
|
||||
case kPidScalaRootKey: {
|
||||
slotI32 = &_state.scalaRootKey;
|
||||
value = kParamScalaRootKey.denormalize(normValue);
|
||||
value = kParamScalaRootKeyRange.denormalize(normValue);
|
||||
break;
|
||||
}
|
||||
case kPidTuningFrequency: {
|
||||
slotF32 = &_state.tuningFrequency;
|
||||
value = kParamTuningFrequency.denormalize(normValue);
|
||||
value = kParamTuningFrequencyRange.denormalize(normValue);
|
||||
break;
|
||||
}
|
||||
case kPidStretchedTuning: {
|
||||
slotF32 = &_state.stretchedTuning;
|
||||
value = kParamStretchedTuning.denormalize(normValue);
|
||||
value = kParamStretchedTuningRange.denormalize(normValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -244,9 +244,9 @@ tresult PLUGIN_API SfizzVstController::setComponentState(IBStream* state)
|
|||
setParamNormalized(kPidNumVoices, kParamNumVoicesRange.normalize(s.numVoices));
|
||||
setParamNormalized(kPidOversampling, kParamOversamplingRange.normalize(s.oversamplingLog2));
|
||||
setParamNormalized(kPidPreloadSize, kParamPreloadSizeRange.normalize(s.preloadSize));
|
||||
setParamNormalized(kPidScalaRootKey, kParamScalaRootKey.normalize(s.scalaRootKey));
|
||||
setParamNormalized(kPidTuningFrequency, kParamTuningFrequency.normalize(s.tuningFrequency));
|
||||
setParamNormalized(kPidStretchedTuning, kParamStretchedTuning.normalize(s.stretchedTuning));
|
||||
setParamNormalized(kPidScalaRootKey, kParamScalaRootKeyRange.normalize(s.scalaRootKey));
|
||||
setParamNormalized(kPidTuningFrequency, kParamTuningFrequencyRange.normalize(s.tuningFrequency));
|
||||
setParamNormalized(kPidStretchedTuning, kParamStretchedTuningRange.normalize(s.stretchedTuning));
|
||||
|
||||
for (StateListener* listener : _stateListeners)
|
||||
listener->onStateChanged();
|
||||
|
|
|
|||
|
|
@ -6,18 +6,18 @@
|
|||
|
||||
#include "SfizzVstEditor.h"
|
||||
#include "SfizzVstState.h"
|
||||
#include "GUIComponents.h"
|
||||
#include "editor/Editor.h"
|
||||
#include "editor/EditIds.h"
|
||||
#if !defined(__APPLE__) && !defined(_WIN32)
|
||||
#include "X11RunLoop.h"
|
||||
#endif
|
||||
|
||||
using namespace VSTGUI;
|
||||
|
||||
static ViewRect sfizzUiViewRect {0, 0, 482, 225};
|
||||
static ViewRect sfizzUiViewRect { 0, 0, Editor::viewWidth, Editor::viewHeight };
|
||||
|
||||
SfizzVstEditor::SfizzVstEditor(void *controller)
|
||||
: VSTGUIEditor(controller, &sfizzUiViewRect),
|
||||
_logo("logo.png")
|
||||
: VSTGUIEditor(controller, &sfizzUiViewRect)
|
||||
{
|
||||
getController()->addSfizzStateListener(this);
|
||||
}
|
||||
|
|
@ -45,7 +45,11 @@ bool PLUGIN_API SfizzVstEditor::open(void* parent, const VSTGUI::PlatformType& p
|
|||
config = &x11config;
|
||||
#endif
|
||||
|
||||
createFrameContents();
|
||||
Editor* editor = editor_.get();
|
||||
if (!editor) {
|
||||
editor = new Editor(*this);
|
||||
editor_.reset(editor);
|
||||
}
|
||||
updateStateDisplay();
|
||||
|
||||
if (!frame->open(parent, platformType, config)) {
|
||||
|
|
@ -53,6 +57,8 @@ bool PLUGIN_API SfizzVstEditor::open(void* parent, const VSTGUI::PlatformType& p
|
|||
return false;
|
||||
}
|
||||
|
||||
editor->open(*frame);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -60,121 +66,16 @@ void PLUGIN_API SfizzVstEditor::close()
|
|||
{
|
||||
CFrame *frame = this->frame;
|
||||
if (frame) {
|
||||
frame->removeAll();
|
||||
if (editor_)
|
||||
editor_->close();
|
||||
if (frame->getNbReference() != 1)
|
||||
frame->forget ();
|
||||
else {
|
||||
frame->forget();
|
||||
else
|
||||
frame->close();
|
||||
this->frame = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
void SfizzVstEditor::valueChanged(CControl* ctl)
|
||||
{
|
||||
int32_t tag = ctl->getTag();
|
||||
float value = ctl->getValue();
|
||||
float valueNorm = ctl->getValueNormalized();
|
||||
SfizzVstController* controller = getController();
|
||||
|
||||
switch (tag) {
|
||||
case kTagLoadSfzFile:
|
||||
if (value != 1)
|
||||
break;
|
||||
|
||||
Call::later([this]() { chooseSfzFile(); });
|
||||
break;
|
||||
|
||||
case kTagLoadScalaFile:
|
||||
if (value != 1)
|
||||
break;
|
||||
|
||||
Call::later([this]() { chooseScalaFile(); });
|
||||
break;
|
||||
|
||||
case kTagSetVolume:
|
||||
controller->setParamNormalized(kPidVolume, valueNorm);
|
||||
controller->performEdit(kPidVolume, valueNorm);
|
||||
updateVolumeLabel(value);
|
||||
break;
|
||||
|
||||
case kTagSetNumVoices:
|
||||
controller->setParamNormalized(kPidNumVoices, valueNorm);
|
||||
controller->performEdit(kPidNumVoices, valueNorm);
|
||||
updateNumVoicesLabel(static_cast<int>(value));
|
||||
break;
|
||||
|
||||
case kTagSetOversampling:
|
||||
controller->setParamNormalized(kPidOversampling, valueNorm);
|
||||
controller->performEdit(kPidOversampling, valueNorm);
|
||||
updateOversamplingLabel(static_cast<int>(value));
|
||||
break;
|
||||
|
||||
case kTagSetPreloadSize:
|
||||
controller->setParamNormalized(kPidPreloadSize, valueNorm);
|
||||
controller->performEdit(kPidPreloadSize, valueNorm);
|
||||
updatePreloadSizeLabel(static_cast<int>(value));
|
||||
break;
|
||||
|
||||
case kTagSetScalaRootKey:
|
||||
controller->setParamNormalized(kPidScalaRootKey, valueNorm);
|
||||
controller->performEdit(kPidScalaRootKey, valueNorm);
|
||||
updateScalaRootKeyLabel(static_cast<int>(value));
|
||||
break;
|
||||
|
||||
case kTagSetTuningFrequency:
|
||||
controller->setParamNormalized(kPidTuningFrequency, valueNorm);
|
||||
controller->performEdit(kPidTuningFrequency, valueNorm);
|
||||
updateTuningFrequencyLabel(value);
|
||||
break;
|
||||
|
||||
case kTagSetStretchedTuning:
|
||||
controller->setParamNormalized(kPidStretchedTuning, valueNorm);
|
||||
controller->performEdit(kPidStretchedTuning, valueNorm);
|
||||
updateStretchedTuningLabel(value);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (tag >= kTagFirstChangePanel && tag <= kTagLastChangePanel)
|
||||
setActivePanel(tag - kTagFirstChangePanel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SfizzVstEditor::enterOrLeaveEdit(CControl* ctl, bool enter)
|
||||
{
|
||||
int32_t tag = ctl->getTag();
|
||||
Vst::ParamID id;
|
||||
|
||||
switch (tag) {
|
||||
case kTagSetVolume: id = kPidVolume; break;
|
||||
case kTagSetNumVoices: id = kPidNumVoices; break;
|
||||
case kTagSetOversampling: id = kPidOversampling; break;
|
||||
case kTagSetPreloadSize: id = kPidPreloadSize; break;
|
||||
case kTagSetScalaRootKey: id = kPidScalaRootKey; break;
|
||||
case kTagSetTuningFrequency: id = kPidTuningFrequency; break;
|
||||
case kTagSetStretchedTuning: id = kPidStretchedTuning; break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
SfizzVstController* controller = getController();
|
||||
if (enter)
|
||||
controller->beginEdit(id);
|
||||
else
|
||||
controller->endEdit(id);
|
||||
}
|
||||
|
||||
void SfizzVstEditor::controlBeginEdit(CControl* ctl)
|
||||
{
|
||||
enterOrLeaveEdit(ctl, true);
|
||||
}
|
||||
|
||||
void SfizzVstEditor::controlEndEdit(CControl* ctl)
|
||||
{
|
||||
enterOrLeaveEdit(ctl, false);
|
||||
}
|
||||
|
||||
CMessageResult SfizzVstEditor::notify(CBaseObject* sender, const char* message)
|
||||
{
|
||||
CMessageResult result = VSTGUIEditor::notify(sender, message);
|
||||
|
|
@ -205,20 +106,83 @@ void SfizzVstEditor::onStateChanged()
|
|||
}
|
||||
|
||||
///
|
||||
void SfizzVstEditor::chooseSfzFile()
|
||||
void SfizzVstEditor::uiSendValue(EditId id, const EditValue& v)
|
||||
{
|
||||
SharedPointer<CNewFileSelector> fs(CNewFileSelector::create(frame));
|
||||
if (id == EditId::SfzFile)
|
||||
loadSfzFile(v.to_string());
|
||||
else if (id == EditId::ScalaFile)
|
||||
loadScalaFile(v.to_string());
|
||||
else {
|
||||
SfizzVstController* ctrl = getController();
|
||||
|
||||
fs->setTitle("Load SFZ file");
|
||||
fs->setDefaultExtension(CFileExtension("SFZ", "sfz"));
|
||||
auto normalizeAndSet = [ctrl](Vst::ParamID pid, const SfizzParameterRange& range, float value) {
|
||||
float normValue = range.normalize(value);
|
||||
ctrl->setParamNormalized(pid, normValue);
|
||||
ctrl->performEdit(pid, normValue);
|
||||
};
|
||||
|
||||
if (fs->runModal()) {
|
||||
UTF8StringPtr file = fs->getSelectedFile(0);
|
||||
if (file)
|
||||
loadSfzFile(file);
|
||||
switch (id) {
|
||||
case EditId::Volume:
|
||||
normalizeAndSet(kPidVolume, kParamVolumeRange, v.to_float());
|
||||
break;
|
||||
case EditId::Polyphony:
|
||||
normalizeAndSet(kPidNumVoices, kParamNumVoicesRange, v.to_float());
|
||||
break;
|
||||
case EditId::Oversampling:
|
||||
{
|
||||
const int32 value = static_cast<int32>(v.to_float());
|
||||
|
||||
int32 log2Value = 0;
|
||||
for (int32 f = value; f > 1; f /= 2)
|
||||
++log2Value;
|
||||
|
||||
normalizeAndSet(kPidOversampling, kParamOversamplingRange, log2Value);
|
||||
}
|
||||
break;
|
||||
case EditId::PreloadSize:
|
||||
normalizeAndSet(kPidPreloadSize, kParamPreloadSizeRange, v.to_float());
|
||||
break;
|
||||
case EditId::ScalaRootKey:
|
||||
normalizeAndSet(kPidScalaRootKey, kParamScalaRootKeyRange, v.to_float());
|
||||
break;
|
||||
case EditId::TuningFrequency:
|
||||
normalizeAndSet(kPidTuningFrequency, kParamTuningFrequencyRange, v.to_float());
|
||||
break;
|
||||
case EditId::StretchTuning:
|
||||
normalizeAndSet(kPidStretchedTuning, kParamStretchedTuningRange, v.to_float());
|
||||
break;
|
||||
|
||||
case EditId::UIActivePanel:
|
||||
ctrl->getSfizzUiState().activePanel = static_cast<int32>(v.to_float());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SfizzVstEditor::uiBeginSend(EditId id)
|
||||
{
|
||||
Vst::ParamID pid = parameterOfEditId(id);
|
||||
if (pid != -1)
|
||||
getController()->beginEdit(pid);
|
||||
}
|
||||
|
||||
void SfizzVstEditor::uiEndSend(EditId id)
|
||||
{
|
||||
Vst::ParamID pid = parameterOfEditId(id);
|
||||
if (pid != -1)
|
||||
getController()->endEdit(pid);
|
||||
}
|
||||
|
||||
void SfizzVstEditor::uiSendMIDI(const uint8_t* msg, uint32_t len)
|
||||
{
|
||||
// TODO send MIDI...
|
||||
|
||||
}
|
||||
|
||||
///
|
||||
void SfizzVstEditor::loadSfzFile(const std::string& filePath)
|
||||
{
|
||||
SfizzVstController* ctl = getController();
|
||||
|
|
@ -233,22 +197,6 @@ void SfizzVstEditor::loadSfzFile(const std::string& filePath)
|
|||
Vst::IAttributeList* attr = msg->getAttributes();
|
||||
attr->setBinary("File", filePath.data(), filePath.size());
|
||||
ctl->sendMessage(msg);
|
||||
|
||||
updateSfzFileLabel(filePath);
|
||||
}
|
||||
|
||||
void SfizzVstEditor::chooseScalaFile()
|
||||
{
|
||||
SharedPointer<CNewFileSelector> fs(CNewFileSelector::create(frame));
|
||||
|
||||
fs->setTitle("Load Scala file");
|
||||
fs->setDefaultExtension(CFileExtension("SCL", "scl"));
|
||||
|
||||
if (fs->runModal()) {
|
||||
UTF8StringPtr file = fs->getSelectedFile(0);
|
||||
if (file)
|
||||
loadScalaFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
void SfizzVstEditor::loadScalaFile(const std::string& filePath)
|
||||
|
|
@ -265,414 +213,6 @@ void SfizzVstEditor::loadScalaFile(const std::string& filePath)
|
|||
Vst::IAttributeList* attr = msg->getAttributes();
|
||||
attr->setBinary("File", filePath.data(), filePath.size());
|
||||
ctl->sendMessage(msg);
|
||||
|
||||
updateScalaFileLabel(filePath);
|
||||
}
|
||||
|
||||
void SfizzVstEditor::createFrameContents()
|
||||
{
|
||||
SfizzVstController* controller = getController();
|
||||
const SfizzUiState& uiState = controller->getSfizzUiState();
|
||||
|
||||
CFrame* frame = this->frame;
|
||||
CRect bounds = frame->getViewSize();
|
||||
|
||||
frame->setBackgroundColor(CColor(0xff, 0xff, 0xff));
|
||||
|
||||
CRect bottomRow = bounds;
|
||||
bottomRow.top = bottomRow.bottom - 30;
|
||||
|
||||
CRect topRow = bounds;
|
||||
topRow.bottom = topRow.top + 30;
|
||||
|
||||
CViewContainer* panel;
|
||||
_activePanel = std::max(0, std::min(kNumPanels - 1, static_cast<int>(uiState.activePanel)));
|
||||
|
||||
CRect topLeftLabelBox = topRow;
|
||||
topLeftLabelBox.right -= 20 * kNumPanels;
|
||||
|
||||
// general panel
|
||||
{
|
||||
panel = new CViewContainer(bounds);
|
||||
frame->addView(panel);
|
||||
panel->setTransparency(true);
|
||||
|
||||
CKickButton* sfizzButton = new CKickButton(bounds, this, kTagLoadSfzFile, &_logo);
|
||||
panel->addView(sfizzButton);
|
||||
|
||||
CTextLabel* topLeftLabel = new CTextLabel(topLeftLabelBox, "No file loaded");
|
||||
topLeftLabel->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
topLeftLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
panel->addView(topLeftLabel);
|
||||
_sfzFileLabel = topLeftLabel;
|
||||
|
||||
_subPanels[kPanelGeneral] = panel;
|
||||
}
|
||||
|
||||
// settings panel
|
||||
{
|
||||
panel = new CViewContainer(bounds);
|
||||
frame->addView(panel);
|
||||
panel->setTransparency(true);
|
||||
|
||||
CTextLabel* topLeftLabel = new CTextLabel(topLeftLabelBox, "Settings");
|
||||
topLeftLabel->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
topLeftLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
panel->addView(topLeftLabel);
|
||||
|
||||
CRect row = topRow;
|
||||
row.top += 45.0;
|
||||
row.bottom += 45.0;
|
||||
row.left += 20.0;
|
||||
row.right -= 20.0;
|
||||
|
||||
static const CCoord interRow = 35.0;
|
||||
static const CCoord interColumn = 20.0;
|
||||
static const int numColumns = 3;
|
||||
|
||||
auto nthColumn = [&row](int colIndex) -> CRect {
|
||||
CRect div = row;
|
||||
CCoord columnWidth = (div.right - div.left + interColumn) / numColumns - interColumn;
|
||||
div.left = div.left + colIndex * (columnWidth + interColumn);
|
||||
div.right = div.left + columnWidth;
|
||||
return div;
|
||||
};
|
||||
|
||||
CTextLabel* label;
|
||||
SimpleSlider* slider;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Volume");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
slider = new SimpleSlider(nthColumn(1), this, kTagSetVolume);
|
||||
panel->addView(slider);
|
||||
adjustMinMaxToRangeParam(slider, kPidVolume);
|
||||
_volumeSlider = slider;
|
||||
label = new CTextLabel(nthColumn(2), "");
|
||||
_volumeLabel = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Polyphony");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
slider = new SimpleSlider(nthColumn(1), this, kTagSetNumVoices);
|
||||
panel->addView(slider);
|
||||
adjustMinMaxToRangeParam(slider, kPidNumVoices);
|
||||
_numVoicesSlider = slider;
|
||||
label = new CTextLabel(nthColumn(2), "");
|
||||
_numVoicesLabel = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Oversampling");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
slider = new SimpleSlider(nthColumn(1), this, kTagSetOversampling);
|
||||
panel->addView(slider);
|
||||
adjustMinMaxToRangeParam(slider, kPidOversampling);
|
||||
_oversamplingSlider = slider;
|
||||
label = new CTextLabel(nthColumn(2), "");
|
||||
_oversamplingLabel = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Preload size");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
slider = new SimpleSlider(nthColumn(1), this, kTagSetPreloadSize);
|
||||
panel->addView(slider);
|
||||
adjustMinMaxToRangeParam(slider, kPidPreloadSize);
|
||||
_preloadSizeSlider = slider;
|
||||
label = new CTextLabel(nthColumn(2), "");
|
||||
_preloadSizeLabel = label;
|
||||
panel->addView(label);
|
||||
|
||||
_subPanels[kPanelSettings] = panel;
|
||||
}
|
||||
|
||||
// tuning panel
|
||||
{
|
||||
panel = new CViewContainer(bounds);
|
||||
frame->addView(panel);
|
||||
panel->setTransparency(true);
|
||||
|
||||
CTextLabel* topLeftLabel = new CTextLabel(topLeftLabelBox, "Tuning");
|
||||
topLeftLabel->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
topLeftLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
panel->addView(topLeftLabel);
|
||||
|
||||
CRect row = topRow;
|
||||
row.top += 45.0;
|
||||
row.bottom += 45.0;
|
||||
row.left += 20.0;
|
||||
row.right -= 20.0;
|
||||
|
||||
static const CCoord interRow = 35.0;
|
||||
static const CCoord interColumn = 20.0;
|
||||
static const int numColumns = 3;
|
||||
|
||||
auto nthColumn = [&row](int colIndex) -> CRect {
|
||||
CRect div = row;
|
||||
CCoord columnWidth = (div.right - div.left + interColumn) / numColumns - interColumn;
|
||||
div.left = div.left + colIndex * (columnWidth + interColumn);
|
||||
div.right = div.left + columnWidth;
|
||||
return div;
|
||||
};
|
||||
|
||||
CTextLabel* label;
|
||||
SimpleSlider* slider;
|
||||
CTextButton* textbutton;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Scala file");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
textbutton = new CTextButton(nthColumn(1), this, kTagLoadScalaFile, "Choose");
|
||||
panel->addView(textbutton);
|
||||
label = new CTextLabel(nthColumn(2), "");
|
||||
_scalaFileLabel = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Scala root key");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
slider = new SimpleSlider(nthColumn(1), this, kTagSetScalaRootKey);
|
||||
panel->addView(slider);
|
||||
adjustMinMaxToRangeParam(slider, kPidScalaRootKey);
|
||||
_scalaRootKeySlider = slider;
|
||||
label = new CTextLabel(nthColumn(2), "");
|
||||
_scalaRootKeyLabel = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Tuning frequency");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
slider = new SimpleSlider(nthColumn(1), this, kTagSetTuningFrequency);
|
||||
panel->addView(slider);
|
||||
adjustMinMaxToRangeParam(slider, kPidTuningFrequency);
|
||||
_tuningFrequencySlider = slider;
|
||||
label = new CTextLabel(nthColumn(2), "");
|
||||
_tuningFrequencyLabel = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Stretched tuning");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
slider = new SimpleSlider(nthColumn(1), this, kTagSetStretchedTuning);
|
||||
panel->addView(slider);
|
||||
adjustMinMaxToRangeParam(slider, kPidStretchedTuning);
|
||||
_stretchedTuningSlider = slider;
|
||||
label = new CTextLabel(nthColumn(2), "");
|
||||
_stretchedTuningLabel = label;
|
||||
panel->addView(label);
|
||||
|
||||
_subPanels[kPanelTuning] = panel;
|
||||
}
|
||||
|
||||
// info panel
|
||||
{
|
||||
panel = new CViewContainer(bounds);
|
||||
frame->addView(panel);
|
||||
panel->setTransparency(true);
|
||||
|
||||
CTextLabel* topLeftLabel = new CTextLabel(topLeftLabelBox, "Information");
|
||||
topLeftLabel->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
topLeftLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
panel->addView(topLeftLabel);
|
||||
|
||||
CRect row = topRow;
|
||||
row.top += 45.0;
|
||||
row.bottom += 45.0;
|
||||
row.left += 20.0;
|
||||
row.right -= 20.0;
|
||||
|
||||
static const CCoord interRow = 20.0;
|
||||
static const CCoord interColumn = 20.0;
|
||||
static const int numColumns = 3;
|
||||
|
||||
auto nthColumn = [&row](int colIndex) -> CRect {
|
||||
CRect div = row;
|
||||
CCoord columnWidth = (div.right - div.left + interColumn) / numColumns - interColumn;
|
||||
div.left = div.left + colIndex * (columnWidth + interColumn);
|
||||
div.right = div.left + columnWidth;
|
||||
return div;
|
||||
};
|
||||
|
||||
CTextLabel* label;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Curves");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
label = new CTextLabel(nthColumn(1), "");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
_infoCurvesLabel = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Masters");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
label = new CTextLabel(nthColumn(1), "");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
_infoMastersLabel = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Groups");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
label = new CTextLabel(nthColumn(1), "");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
_infoGroupsLabel = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Regions");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
label = new CTextLabel(nthColumn(1), "");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
_infoRegionsLabel = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Samples");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
label = new CTextLabel(nthColumn(1), "");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
_infoSamplesLabel = label;
|
||||
panel->addView(label);
|
||||
|
||||
row.top += interRow;
|
||||
row.bottom += interRow;
|
||||
|
||||
label = new CTextLabel(nthColumn(0), "Voices");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
panel->addView(label);
|
||||
label = new CTextLabel(nthColumn(1), "");
|
||||
label->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
label->setHoriAlign(kLeftText);
|
||||
_infoVoicesLabel = label;
|
||||
panel->addView(label);
|
||||
|
||||
_subPanels[kPanelInfo] = panel;
|
||||
}
|
||||
|
||||
// all panels
|
||||
for (unsigned currentPanel = 0; currentPanel < kNumPanels; ++currentPanel) {
|
||||
panel = _subPanels[currentPanel];
|
||||
|
||||
CTextLabel* descLabel = new CTextLabel(
|
||||
bottomRow, "Paul Ferrand and the SFZ Tools work group");
|
||||
descLabel->setFontColor(CColor(0x00, 0x00, 0x00));
|
||||
descLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
|
||||
panel->addView(descLabel);
|
||||
|
||||
for (unsigned i = 0; i < kNumPanels; ++i) {
|
||||
CRect btnRect = topRow;
|
||||
btnRect.left = topRow.right - (kNumPanels - i) * 50;
|
||||
btnRect.right = btnRect.left + 50;
|
||||
|
||||
const char *text;
|
||||
switch (i) {
|
||||
case kPanelGeneral: text = "File"; break;
|
||||
case kPanelSettings: text = "Setup"; break;
|
||||
case kPanelTuning: text = "Tuning"; break;
|
||||
case kPanelInfo: text = "Info"; break;
|
||||
default: text = "?"; break;
|
||||
}
|
||||
|
||||
CTextButton* changePanelButton = new CTextButton(btnRect, this, kTagFirstChangePanel + i, text);
|
||||
panel->addView(changePanelButton);
|
||||
|
||||
changePanelButton->setRoundRadius(0.0);
|
||||
}
|
||||
|
||||
panel->setVisible(currentPanel == _activePanel);
|
||||
}
|
||||
}
|
||||
|
||||
void SfizzVstEditor::updateStateDisplay()
|
||||
|
|
@ -686,196 +226,38 @@ void SfizzVstEditor::updateStateDisplay()
|
|||
const SfizzPlayState& playState = controller->getSfizzPlayState();
|
||||
|
||||
///
|
||||
updateSfzFileLabel(state.sfzFile);
|
||||
if (_volumeSlider)
|
||||
_volumeSlider->setValue(state.volume);
|
||||
updateVolumeLabel(state.volume);
|
||||
if (_numVoicesSlider)
|
||||
_numVoicesSlider->setValue(state.numVoices);
|
||||
updateNumVoicesLabel(state.numVoices);
|
||||
if (_oversamplingSlider)
|
||||
_oversamplingSlider->setValue(state.oversamplingLog2);
|
||||
updateOversamplingLabel(state.oversamplingLog2);
|
||||
if (_preloadSizeSlider)
|
||||
_preloadSizeSlider->setValue(state.preloadSize);
|
||||
updatePreloadSizeLabel(state.preloadSize);
|
||||
updateScalaFileLabel(state.scalaFile);
|
||||
if (_scalaRootKeySlider)
|
||||
_scalaRootKeySlider->setValue(state.scalaRootKey);
|
||||
updateScalaRootKeyLabel(state.scalaRootKey);
|
||||
if (_tuningFrequencySlider)
|
||||
_tuningFrequencySlider->setValue(state.tuningFrequency);
|
||||
updateTuningFrequencyLabel(state.tuningFrequency);
|
||||
if (_stretchedTuningSlider)
|
||||
_stretchedTuningSlider->setValue(state.stretchedTuning);
|
||||
updateStretchedTuningLabel(state.stretchedTuning);
|
||||
uiReceiveValue(EditId::SfzFile, state.sfzFile);
|
||||
uiReceiveValue(EditId::Volume, state.volume);
|
||||
uiReceiveValue(EditId::Polyphony, state.numVoices);
|
||||
uiReceiveValue(EditId::Oversampling, 1u << state.oversamplingLog2);
|
||||
uiReceiveValue(EditId::PreloadSize, state.preloadSize);
|
||||
uiReceiveValue(EditId::ScalaFile, state.scalaFile);
|
||||
uiReceiveValue(EditId::ScalaRootKey, state.scalaRootKey);
|
||||
uiReceiveValue(EditId::TuningFrequency, state.tuningFrequency);
|
||||
uiReceiveValue(EditId::StretchTuning, state.stretchedTuning);
|
||||
|
||||
///
|
||||
struct InfoLabel { const uint32* src; CTextLabel* dst; };
|
||||
for (const auto& item : {
|
||||
InfoLabel{&playState.curves, _infoCurvesLabel},
|
||||
InfoLabel{&playState.masters, _infoMastersLabel},
|
||||
InfoLabel{&playState.groups, _infoGroupsLabel},
|
||||
InfoLabel{&playState.regions, _infoRegionsLabel},
|
||||
InfoLabel{&playState.preloadedSamples, _infoSamplesLabel},
|
||||
InfoLabel{&playState.activeVoices, _infoVoicesLabel} })
|
||||
{
|
||||
if (item.dst) {
|
||||
char text[64];
|
||||
sprintf(text, "%u", *item.src);
|
||||
text[sizeof(text) - 1] = '\0';
|
||||
item.dst->setText(text);
|
||||
}
|
||||
}
|
||||
uiReceiveValue(EditId::UINumCurves, playState.curves);
|
||||
uiReceiveValue(EditId::UINumMasters, playState.masters);
|
||||
uiReceiveValue(EditId::UINumGroups, playState.groups);
|
||||
uiReceiveValue(EditId::UINumRegions, playState.regions);
|
||||
uiReceiveValue(EditId::UINumPreloadedSamples, playState.preloadedSamples);
|
||||
uiReceiveValue(EditId::UINumActiveVoices, playState.activeVoices);
|
||||
|
||||
///
|
||||
setActivePanel(uiState.activePanel);
|
||||
uiReceiveValue(EditId::UIActivePanel, uiState.activePanel);
|
||||
}
|
||||
|
||||
void SfizzVstEditor::updateSfzFileLabel(const std::string& filePath)
|
||||
Vst::ParamID SfizzVstEditor::parameterOfEditId(EditId id)
|
||||
{
|
||||
updateLabelWithFileName(_sfzFileLabel, filePath);
|
||||
}
|
||||
|
||||
void SfizzVstEditor::updateScalaFileLabel(const std::string& filePath)
|
||||
{
|
||||
updateLabelWithFileName(_scalaFileLabel, filePath);
|
||||
}
|
||||
|
||||
void SfizzVstEditor::updateLabelWithFileName(CTextLabel* label, const std::string& filePath)
|
||||
{
|
||||
if (!label)
|
||||
return;
|
||||
|
||||
std::string fileName;
|
||||
if (filePath.empty())
|
||||
fileName = "<No file>";
|
||||
else {
|
||||
#if defined (_WIN32)
|
||||
size_t pos = filePath.find_last_of("/\\");
|
||||
#else
|
||||
size_t pos = filePath.rfind('/');
|
||||
#endif
|
||||
fileName = (pos != filePath.npos) ?
|
||||
filePath.substr(pos + 1) : filePath;
|
||||
}
|
||||
label->setText(fileName.c_str());
|
||||
}
|
||||
|
||||
void SfizzVstEditor::updateVolumeLabel(float volume)
|
||||
{
|
||||
CTextLabel* label = _volumeLabel;
|
||||
if (!label)
|
||||
return;
|
||||
|
||||
char text[64];
|
||||
sprintf(text, "%.1f dB", volume);
|
||||
text[sizeof(text) - 1] = '\0';
|
||||
label->setText(text);
|
||||
}
|
||||
|
||||
void SfizzVstEditor::updateNumVoicesLabel(int numVoices)
|
||||
{
|
||||
CTextLabel* label = _numVoicesLabel;
|
||||
if (!label)
|
||||
return;
|
||||
|
||||
char text[64];
|
||||
sprintf(text, "%d", numVoices);
|
||||
text[sizeof(text) - 1] = '\0';
|
||||
label->setText(text);
|
||||
}
|
||||
|
||||
void SfizzVstEditor::updateOversamplingLabel(int oversamplingLog2)
|
||||
{
|
||||
CTextLabel* label = _oversamplingLabel;
|
||||
if (!label)
|
||||
return;
|
||||
|
||||
char text[64];
|
||||
sprintf(text, "%dx", 1 << oversamplingLog2);
|
||||
text[sizeof(text) - 1] = '\0';
|
||||
label->setText(text);
|
||||
}
|
||||
|
||||
void SfizzVstEditor::updatePreloadSizeLabel(int preloadSize)
|
||||
{
|
||||
CTextLabel* label = _preloadSizeLabel;
|
||||
if (!label)
|
||||
return;
|
||||
|
||||
char text[64];
|
||||
sprintf(text, "%.1f kB", preloadSize * (1.0 / 1024));
|
||||
text[sizeof(text) - 1] = '\0';
|
||||
label->setText(text);
|
||||
}
|
||||
|
||||
void SfizzVstEditor::updateScalaRootKeyLabel(int rootKey)
|
||||
{
|
||||
CTextLabel* label = _scalaRootKeyLabel;
|
||||
if (!label)
|
||||
return;
|
||||
|
||||
static const char *octNoteNames[12] = {
|
||||
"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B",
|
||||
};
|
||||
|
||||
auto noteName = [](int key) -> std::string
|
||||
{
|
||||
int octNum;
|
||||
int octNoteNum;
|
||||
if (key >= 0) {
|
||||
octNum = key / 12 - 1;
|
||||
octNoteNum = key % 12;
|
||||
}
|
||||
else {
|
||||
octNum = -2 - (key + 1) / -12;
|
||||
octNoteNum = (key % 12 + 12) % 12;
|
||||
}
|
||||
return std::string(octNoteNames[octNoteNum]) + std::to_string(octNum);
|
||||
};
|
||||
|
||||
label->setText(noteName(rootKey));
|
||||
}
|
||||
|
||||
void SfizzVstEditor::updateTuningFrequencyLabel(float tuningFrequency)
|
||||
{
|
||||
CTextLabel* label = _tuningFrequencyLabel;
|
||||
if (!label)
|
||||
return;
|
||||
|
||||
char text[64];
|
||||
sprintf(text, "%.1f", tuningFrequency);
|
||||
text[sizeof(text) - 1] = '\0';
|
||||
label->setText(text);
|
||||
}
|
||||
|
||||
void SfizzVstEditor::updateStretchedTuningLabel(float stretchedTuning)
|
||||
{
|
||||
CTextLabel* label = _stretchedTuningLabel;
|
||||
if (!label)
|
||||
return;
|
||||
|
||||
char text[64];
|
||||
sprintf(text, "%.3f", stretchedTuning);
|
||||
text[sizeof(text) - 1] = '\0';
|
||||
label->setText(text);
|
||||
}
|
||||
|
||||
|
||||
void SfizzVstEditor::setActivePanel(unsigned panelId)
|
||||
{
|
||||
panelId = std::max(0, std::min(kNumPanels - 1, static_cast<int>(panelId)));
|
||||
|
||||
getController()->getSfizzUiState().activePanel = panelId;
|
||||
|
||||
if (_activePanel != panelId) {
|
||||
if (frame)
|
||||
_subPanels[_activePanel]->setVisible(false);
|
||||
|
||||
_activePanel = panelId;
|
||||
|
||||
if (frame)
|
||||
_subPanels[panelId]->setVisible(true);
|
||||
switch (id) {
|
||||
case EditId::Volume: return kPidVolume;
|
||||
case EditId::Polyphony: return kPidNumVoices;
|
||||
case EditId::Oversampling: return kPidOversampling;
|
||||
case EditId::PreloadSize: return kPidPreloadSize;
|
||||
case EditId::ScalaRootKey: return kPidScalaRootKey;
|
||||
case EditId::TuningFrequency: return kPidTuningFrequency;
|
||||
case EditId::StretchTuning: return kPidStretchedTuning;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@
|
|||
|
||||
#pragma once
|
||||
#include "SfizzVstController.h"
|
||||
#include "editor/EditorController.h"
|
||||
#include "public.sdk/source/vst/vstguieditor.h"
|
||||
class Editor;
|
||||
#if !defined(__APPLE__) && !defined(_WIN32)
|
||||
namespace VSTGUI { class RunLoop; }
|
||||
#endif
|
||||
|
|
@ -14,7 +16,7 @@ namespace VSTGUI { class RunLoop; }
|
|||
using namespace Steinberg;
|
||||
using namespace VSTGUI;
|
||||
|
||||
class SfizzVstEditor : public Vst::VSTGUIEditor, public IControlListener, public SfizzVstController::StateListener {
|
||||
class SfizzVstEditor : public Vst::VSTGUIEditor, public SfizzVstController::StateListener, public EditorController {
|
||||
public:
|
||||
explicit SfizzVstEditor(void *controller);
|
||||
~SfizzVstEditor();
|
||||
|
|
@ -27,98 +29,28 @@ public:
|
|||
return static_cast<SfizzVstController*>(Vst::VSTGUIEditor::getController());
|
||||
}
|
||||
|
||||
// IControlListener
|
||||
void valueChanged(CControl* ctl) override;
|
||||
void enterOrLeaveEdit(CControl* ctl, bool enter);
|
||||
void controlBeginEdit(CControl* ctl) override;
|
||||
void controlEndEdit(CControl* ctl) override;
|
||||
|
||||
// VSTGUIEditor
|
||||
CMessageResult notify(CBaseObject* sender, const char* message) override;
|
||||
|
||||
// SfizzVstController::StateListener
|
||||
void onStateChanged() override;
|
||||
|
||||
private:
|
||||
void chooseSfzFile();
|
||||
void loadSfzFile(const std::string& filePath);
|
||||
protected:
|
||||
// EditorController
|
||||
void uiSendValue(EditId id, const EditValue& v) override;
|
||||
void uiBeginSend(EditId id) override;
|
||||
void uiEndSend(EditId id) override;
|
||||
void uiSendMIDI(const uint8_t* msg, uint32_t len) override;
|
||||
|
||||
void chooseScalaFile();
|
||||
private:
|
||||
void loadSfzFile(const std::string& filePath);
|
||||
void loadScalaFile(const std::string& filePath);
|
||||
|
||||
void createFrameContents();
|
||||
void updateStateDisplay();
|
||||
void updateSfzFileLabel(const std::string& filePath);
|
||||
void updateScalaFileLabel(const std::string& filePath);
|
||||
static void updateLabelWithFileName(CTextLabel* label, const std::string& filePath);
|
||||
void updateVolumeLabel(float volume);
|
||||
void updateNumVoicesLabel(int numVoices);
|
||||
void updateOversamplingLabel(int oversamplingLog2);
|
||||
void updatePreloadSizeLabel(int preloadSize);
|
||||
void updateScalaRootKeyLabel(int rootKey);
|
||||
void updateTuningFrequencyLabel(float tuningFrequency);
|
||||
void updateStretchedTuningLabel(float stretchedTuning);
|
||||
void setActivePanel(unsigned panelId);
|
||||
|
||||
template <class Control>
|
||||
void adjustMinMaxToRangeParam(Control* c, Vst::ParamID id)
|
||||
{
|
||||
auto* p = static_cast<Vst::RangeParameter*>(getController()->getParameterObject(id));
|
||||
c->setMin(p->getMin());
|
||||
c->setMax(p->getMax());
|
||||
c->setDefaultValue(p->toPlain(p->getInfo().defaultNormalizedValue));
|
||||
}
|
||||
Vst::ParamID parameterOfEditId(EditId id);
|
||||
|
||||
enum {
|
||||
kPanelGeneral,
|
||||
// kPanelControls,
|
||||
kPanelSettings,
|
||||
kPanelTuning,
|
||||
kPanelInfo,
|
||||
kNumPanels,
|
||||
};
|
||||
|
||||
unsigned _activePanel = 0;
|
||||
CViewContainer* _subPanels[kNumPanels] = {};
|
||||
|
||||
enum {
|
||||
kTagLoadSfzFile,
|
||||
kTagSetVolume,
|
||||
kTagSetNumVoices,
|
||||
kTagSetOversampling,
|
||||
kTagSetPreloadSize,
|
||||
kTagLoadScalaFile,
|
||||
kTagSetScalaRootKey,
|
||||
kTagSetTuningFrequency,
|
||||
kTagSetStretchedTuning,
|
||||
kTagFirstChangePanel,
|
||||
kTagLastChangePanel = kTagFirstChangePanel + kNumPanels - 1,
|
||||
};
|
||||
|
||||
CBitmap _logo;
|
||||
CTextLabel* _sfzFileLabel = nullptr;
|
||||
CTextLabel* _scalaFileLabel = nullptr;
|
||||
CSliderBase *_volumeSlider = nullptr;
|
||||
CTextLabel* _volumeLabel = nullptr;
|
||||
CSliderBase *_numVoicesSlider = nullptr;
|
||||
CTextLabel* _numVoicesLabel = nullptr;
|
||||
CSliderBase *_oversamplingSlider = nullptr;
|
||||
CTextLabel* _oversamplingLabel = nullptr;
|
||||
CSliderBase *_preloadSizeSlider = nullptr;
|
||||
CTextLabel* _preloadSizeLabel = nullptr;
|
||||
CSliderBase *_scalaRootKeySlider = nullptr;
|
||||
CTextLabel* _scalaRootKeyLabel = nullptr;
|
||||
CSliderBase *_tuningFrequencySlider = nullptr;
|
||||
CTextLabel* _tuningFrequencyLabel = nullptr;
|
||||
CSliderBase *_stretchedTuningSlider = nullptr;
|
||||
CTextLabel* _stretchedTuningLabel = nullptr;
|
||||
|
||||
CTextLabel* _infoCurvesLabel = nullptr;
|
||||
CTextLabel* _infoMastersLabel = nullptr;
|
||||
CTextLabel* _infoGroupsLabel = nullptr;
|
||||
CTextLabel* _infoRegionsLabel = nullptr;
|
||||
CTextLabel* _infoSamplesLabel = nullptr;
|
||||
CTextLabel* _infoVoicesLabel = nullptr;
|
||||
std::unique_ptr<Editor> editor_;
|
||||
|
||||
#if !defined(__APPLE__) && !defined(_WIN32)
|
||||
SharedPointer<RunLoop> _runLoop;
|
||||
|
|
|
|||
|
|
@ -289,15 +289,15 @@ void SfizzVstProcessor::processParameterChanges(Vst::IParameterChanges& pc)
|
|||
break;
|
||||
case kPidScalaRootKey:
|
||||
if (pointCount > 0 && vq->getPoint(pointCount - 1, sampleOffset, value) == kResultTrue)
|
||||
_state.scalaRootKey = static_cast<int32>(kParamScalaRootKey.denormalize(value));
|
||||
_state.scalaRootKey = static_cast<int32>(kParamScalaRootKeyRange.denormalize(value));
|
||||
break;
|
||||
case kPidTuningFrequency:
|
||||
if (pointCount > 0 && vq->getPoint(pointCount - 1, sampleOffset, value) == kResultTrue)
|
||||
_state.tuningFrequency = kParamTuningFrequency.denormalize(value);
|
||||
_state.tuningFrequency = kParamTuningFrequencyRange.denormalize(value);
|
||||
break;
|
||||
case kPidStretchedTuning:
|
||||
if (pointCount > 0 && vq->getPoint(pointCount - 1, sampleOffset, value) == kResultTrue)
|
||||
_state.stretchedTuning = kParamStretchedTuning.denormalize(value);
|
||||
_state.stretchedTuning = kParamStretchedTuningRange.denormalize(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,6 +99,6 @@ static constexpr SfizzParameterRange kParamVolumeRange(0.0, -60.0, +6.0);
|
|||
static constexpr SfizzParameterRange kParamNumVoicesRange(64.0, 1.0, 256.0);
|
||||
static constexpr SfizzParameterRange kParamOversamplingRange(0.0, 0.0, 3.0);
|
||||
static constexpr SfizzParameterRange kParamPreloadSizeRange(8192.0, 1024.0, 65536.0);
|
||||
static constexpr SfizzParameterRange kParamScalaRootKey(60.0, 0.0, 127.0);
|
||||
static constexpr SfizzParameterRange kParamTuningFrequency(440.0, 300.0, 500.0);
|
||||
static constexpr SfizzParameterRange kParamStretchedTuning(0.0, 0.0, 1.0);
|
||||
static constexpr SfizzParameterRange kParamScalaRootKeyRange(60.0, 0.0, 127.0);
|
||||
static constexpr SfizzParameterRange kParamTuningFrequencyRange(440.0, 300.0, 500.0);
|
||||
static constexpr SfizzParameterRange kParamStretchedTuningRange(0.0, 0.0, 1.0);
|
||||
|
|
|
|||
|
|
@ -63,222 +63,7 @@ endfunction()
|
|||
|
||||
# --- VSTGUI ---
|
||||
function(plugin_add_vstgui NAME)
|
||||
target_sources("${NAME}" PRIVATE
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/animation/animations.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/animation/animator.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/animation/timingfunctions.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/cbitmap.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/cbitmapfilter.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/ccolor.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/cdatabrowser.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/cdrawcontext.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/cdrawmethods.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/cdropsource.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/cfileselector.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/cfont.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/cframe.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/cgradientview.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/cgraphicspath.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/clayeredviewcontainer.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/clinestyle.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/coffscreencontext.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/cautoanimation.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/cbuttons.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/ccolorchooser.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/ccontrol.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/cfontchooser.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/cknob.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/clistcontrol.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/cmoviebitmap.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/cmoviebutton.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/coptionmenu.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/cparamdisplay.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/cscrollbar.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/csearchtextedit.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/csegmentbutton.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/cslider.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/cspecialdigit.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/csplashscreen.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/cstringlist.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/cswitch.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/ctextedit.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/ctextlabel.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/cvumeter.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/controls/cxypad.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/copenglview.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/cpoint.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/crect.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/crowcolumnview.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/cscrollview.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/cshadowviewcontainer.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/csplitview.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/cstring.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/ctabview.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/ctooltipsupport.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/cview.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/cviewcontainer.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/cvstguitimer.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/genericstringlistdatabrowsersource.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/common/genericoptionmenu.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/vstguidebug.cpp")
|
||||
|
||||
if(WIN32)
|
||||
target_sources("${NAME}" PRIVATE
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/common/fileresourceinputstream.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/win32/direct2d/d2dbitmap.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/win32/direct2d/d2ddrawcontext.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/win32/direct2d/d2dfont.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/win32/direct2d/d2dgraphicspath.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/win32/win32datapackage.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/win32/win32dragging.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/win32/win32frame.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/win32/win32openglview.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/win32/win32optionmenu.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/win32/win32support.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/win32/win32textedit.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/win32/winfileselector.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/win32/winstring.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/win32/wintimer.cpp")
|
||||
elseif(APPLE)
|
||||
target_sources("${NAME}" PRIVATE
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/common/fileresourceinputstream.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/common/genericoptionmenu.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/common/generictextedit.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/mac/carbon/hiviewframe.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/mac/carbon/hiviewoptionmenu.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/mac/carbon/hiviewtextedit.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/mac/caviewlayer.mm"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/mac/cfontmac.mm"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/mac/cgbitmap.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/mac/cgdrawcontext.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/mac/cocoa/autoreleasepool.mm"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/mac/cocoa/cocoahelpers.mm"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/mac/cocoa/cocoaopenglview.mm"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/mac/cocoa/cocoatextedit.mm"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/mac/cocoa/nsviewdraggingsession.mm"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/mac/cocoa/nsviewframe.mm"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/mac/cocoa/nsviewoptionmenu.mm"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/mac/macclipboard.mm"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/mac/macfileselector.mm"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/mac/macglobals.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/mac/macstring.mm"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/mac/mactimer.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/mac/quartzgraphicspath.cpp")
|
||||
else()
|
||||
target_sources("${NAME}" PRIVATE
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/common/fileresourceinputstream.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/common/generictextedit.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/linux/cairobitmap.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/linux/cairocontext.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/linux/cairofont.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/linux/cairogradient.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/linux/cairopath.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/linux/linuxstring.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/linux/x11fileselector.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/linux/x11frame.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/linux/x11platform.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/linux/x11timer.cpp"
|
||||
"${VST3SDK_BASEDIR}/vstgui4/vstgui/lib/platform/linux/x11utils.cpp")
|
||||
endif()
|
||||
|
||||
target_include_directories("${NAME}" PRIVATE "${VST3SDK_BASEDIR}/vstgui4")
|
||||
|
||||
if(WIN32)
|
||||
target_compile_definitions("${NAME}" PRIVATE "NOMINMAX=1")
|
||||
if (NOT MSVC)
|
||||
# autolinked on MSVC with pragmas
|
||||
find_library(OPENGL32_LIBRARY "opengl32")
|
||||
find_library(D2D1_LIBRARY "d2d1")
|
||||
find_library(DWRITE_LIBRARY "dwrite")
|
||||
find_library(DWMAPI_LIBRARY "dwmapi")
|
||||
find_library(WINDOWSCODECS_LIBRARY "windowscodecs")
|
||||
find_library(SHLWAPI_LIBRARY "shlwapi")
|
||||
target_link_libraries("${NAME}" PRIVATE
|
||||
"${OPENGL32_LIBRARY}"
|
||||
"${D2D1_LIBRARY}"
|
||||
"${DWRITE_LIBRARY}"
|
||||
"${DWMAPI_LIBRARY}"
|
||||
"${WINDOWSCODECS_LIBRARY}"
|
||||
"${SHLWAPI_LIBRARY}")
|
||||
endif()
|
||||
elseif(APPLE)
|
||||
find_library(APPLE_COREFOUNDATION_LIBRARY "CoreFoundation")
|
||||
find_library(APPLE_FOUNDATION_LIBRARY "Foundation")
|
||||
find_library(APPLE_COCOA_LIBRARY "Cocoa")
|
||||
find_library(APPLE_OPENGL_LIBRARY "OpenGL")
|
||||
find_library(APPLE_ACCELERATE_LIBRARY "Accelerate")
|
||||
find_library(APPLE_QUARTZCORE_LIBRARY "QuartzCore")
|
||||
find_library(APPLE_CARBON_LIBRARY "Carbon")
|
||||
find_library(APPLE_AUDIOTOOLBOX_LIBRARY "AudioToolbox")
|
||||
find_library(APPLE_COREAUDIO_LIBRARY "CoreAudio")
|
||||
find_library(APPLE_COREMIDI_LIBRARY "CoreMIDI")
|
||||
target_link_libraries("${NAME}" 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)
|
||||
target_include_directories("${NAME}" 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})
|
||||
target_link_libraries("${NAME}" 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})
|
||||
find_library(DL_LIBRARY "dl")
|
||||
if(DL_LIBRARY)
|
||||
target_link_libraries("${NAME}" PRIVATE "${DL_LIBRARY}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_sources("${NAME}" PRIVATE
|
||||
"${VST3SDK_BASEDIR}/public.sdk/source/vst/vstguieditor.cpp")
|
||||
|
||||
target_include_directories("${NAME}" PRIVATE
|
||||
external/steinberg/src)
|
||||
|
||||
target_link_libraries("${NAME}" PRIVATE sfizz-vstgui)
|
||||
target_sources("${NAME}" PRIVATE "${VST3SDK_BASEDIR}/public.sdk/source/vst/vstguieditor.cpp")
|
||||
target_compile_definitions("${NAME}" PRIVATE "SMTG_MODULE_IS_BUNDLE=1")
|
||||
|
||||
if(${CMAKE_BUILD_TYPE} MATCHES "Debug")
|
||||
target_compile_definitions("${NAME}" PRIVATE "DEVELOPMENT")
|
||||
endif()
|
||||
|
||||
if(${CMAKE_BUILD_TYPE} MATCHES "Release")
|
||||
target_compile_definitions("${NAME}" PRIVATE "RELEASE")
|
||||
endif()
|
||||
endfunction()
|
||||
|
|
|
|||
1
vst/external/VST_SDK/VST3_SDK/vstgui4
vendored
1
vst/external/VST_SDK/VST3_SDK/vstgui4
vendored
|
|
@ -1 +0,0 @@
|
|||
Subproject commit c6a7f607c21a7353e922a6d45e54d6c56d5a6745
|
||||
Loading…
Add table
Reference in a new issue