diff --git a/.gitmodules b/.gitmodules index 7a652206..1247ca5f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 diff --git a/.travis.yml b/.travis.yml index 7286a566..1fb67fdf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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: diff --git a/.travis/script_mingw.sh b/.travis/script_mingw.sh index 2f1f545f..e09db92a 100755 --- a/.travis/script_mingw.sh +++ b/.travis/script_mingw.sh @@ -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) diff --git a/.travis/script_moddevices.sh b/.travis/script_moddevices.sh index 649dbb3d..278b7045 100755 --- a/.travis/script_moddevices.sh +++ b/.travis/script_moddevices.sh @@ -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) diff --git a/.travis/script_plugins.sh b/.travis/script_plugins.sh index 89eaf8ac..66e6b09f 100755 --- a/.travis/script_plugins.sh +++ b/.travis/script_plugins.sh @@ -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) diff --git a/.travis/script_test.sh b/.travis/script_test.sh index 844ec9b9..1a23a092 100755 --- a/.travis/script_test.sh +++ b/.travis/script_test.sh @@ -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 \ .. diff --git a/CMakeLists.txt b/CMakeLists.txt index cbc3945b..0158e93a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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() diff --git a/cmake/LV2Config.cmake b/cmake/LV2Config.cmake index 95c54bdf..6b9d9b76 100644 --- a/cmake/LV2Config.cmake +++ b/cmake/LV2Config.cmake @@ -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}]") diff --git a/cmake/SfizzConfig.cmake b/cmake/SfizzConfig.cmake index 95b462e6..ae6aec60 100644 --- a/cmake/SfizzConfig.cmake +++ b/cmake/SfizzConfig.cmake @@ -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} diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt new file mode 100644 index 00000000..977f36a4 --- /dev/null +++ b/editor/CMakeLists.txt @@ -0,0 +1,16 @@ +set(VSTGUI_BASEDIR "${CMAKE_CURRENT_SOURCE_DIR}/external/vstgui4") +include("cmake/Vstgui.cmake") + +# 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 absl::strings) diff --git a/editor/cmake/Vstgui.cmake b/editor/cmake/Vstgui.cmake new file mode 100644 index 00000000..92f85f03 --- /dev/null +++ b/editor/cmake/Vstgui.cmake @@ -0,0 +1,209 @@ +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() diff --git a/vst/external/VST_SDK/VST3_SDK/vstgui4 b/editor/external/vstgui4 similarity index 100% rename from vst/external/VST_SDK/VST3_SDK/vstgui4 rename to editor/external/vstgui4 diff --git a/editor/src/editor/EditIds.cpp b/editor/src/editor/EditIds.cpp new file mode 100644 index 00000000..1d148fb0 --- /dev/null +++ b/editor/src/editor/EditIds.cpp @@ -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 }; + } +} diff --git a/editor/src/editor/EditIds.h b/editor/src/editor/EditIds.h new file mode 100644 index 00000000..660853db --- /dev/null +++ b/editor/src/editor/EditIds.h @@ -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 + +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); +}; diff --git a/editor/src/editor/Editor.cpp b/editor/src/editor/Editor.cpp new file mode 100644 index 00000000..c4d247c8 --- /dev/null +++ b/editor/src/editor/Editor.cpp @@ -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 +#include +#include + +#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 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 + 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 = absl::get(v); + updateSfzFileLabel(value); + } + break; + case EditId::Volume: + { + const float value = absl::get(v); + if (volumeSlider_) + volumeSlider_->setValue(value); + updateVolumeLabel(value); + } + break; + case EditId::Polyphony: + { + const int value = static_cast(absl::get(v)); + if (numVoicesSlider_) + numVoicesSlider_->setValue(value); + updateNumVoicesLabel(value); + } + break; + case EditId::Oversampling: + { + const int value = static_cast(absl::get(v)); + + 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(absl::get(v)); + if (preloadSizeSlider_) + preloadSizeSlider_->setValue(value); + updatePreloadSizeLabel(value); + } + break; + case EditId::ScalaFile: + { + const std::string& value = absl::get(v); + updateScalaFileLabel(value); + } + break; + case EditId::ScalaRootKey: + { + const int value = static_cast(absl::get(v)); + if (scalaRootKeySlider_) + scalaRootKeySlider_->setValue(value); + updateScalaRootKeyLabel(value); + } + break; + case EditId::TuningFrequency: + { + const float value = absl::get(v); + if (tuningFrequencySlider_) + tuningFrequencySlider_->setValue(value); + updateTuningFrequencyLabel(value); + } + break; + case EditId::StretchTuning: + { + const float value = absl::get(v); + if (stretchedTuningSlider_) + stretchedTuningSlider_->setValue(value); + updateStretchedTuningLabel(value); + } + break; + case EditId::UINumCurves: + { + const int value = static_cast(absl::get(v)); + if (CTextLabel* label = infoCurvesLabel_) + formatLabel(label, "%u", value); + } + break; + case EditId::UINumMasters: + { + const int value = static_cast(absl::get(v)); + if (CTextLabel* label = infoMastersLabel_) + formatLabel(label, "%u", value); + } + break; + case EditId::UINumGroups: + { + const int value = static_cast(absl::get(v)); + if (CTextLabel* label = infoGroupsLabel_) + formatLabel(label, "%u", value); + } + break; + case EditId::UINumRegions: + { + const int value = static_cast(absl::get(v)); + if (CTextLabel* label = infoRegionsLabel_) + formatLabel(label, "%u", value); + } + break; + case EditId::UINumPreloadedSamples: + { + const int value = static_cast(absl::get(v)); + if (CTextLabel* label = infoSamplesLabel_) + formatLabel(label, "%u", value); + } + break; + case EditId::UINumActiveVoices: + { + const int value = static_cast(absl::get(v)); + if (CTextLabel* label = infoVoicesLabel_) + formatLabel(label, "%u", value); + } + break; + case EditId::UIActivePanel: + { + const int value = static_cast(absl::get(v)); + setActivePanel(value); + } + break; + } +} + +void Editor::Impl::createFrameContents() +{ + const CRect bounds { 0.0, 0.0, viewWidth, viewHeight }; + CViewContainer* view = new CViewContainer(bounds); + view_ = view; + + view->setBackgroundColor(CColor(0xff, 0xff, 0xff)); + + SharedPointer 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 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 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 = ""; + 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(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(value)); + break; + + case kTagSetOversampling: + ctrl.uiSendValue(EditId::Oversampling, 1 << static_cast(value)); + updateOversamplingLabel(static_cast(value)); + break; + + case kTagSetPreloadSize: + ctrl.uiSendValue(EditId::PreloadSize, value); + updatePreloadSizeLabel(static_cast(value)); + break; + + case kTagSetScalaRootKey: + ctrl.uiSendValue(EditId::ScalaRootKey, value); + updateScalaRootKeyLabel(static_cast(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, 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); +} diff --git a/editor/src/editor/Editor.h b/editor/src/editor/Editor.h new file mode 100644 index 00000000..0c0ae1de --- /dev/null +++ b/editor/src/editor/Editor.h @@ -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 +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_; +}; diff --git a/editor/src/editor/EditorController.h b/editor/src/editor/EditorController.h new file mode 100644 index 00000000..6b6988c1 --- /dev/null +++ b/editor/src/editor/EditorController.h @@ -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 +#include +#include +enum class EditId : int; +typedef absl::variant EditValue; + +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); +} diff --git a/vst/GUIComponents.cpp b/editor/src/editor/GUIComponents.cpp similarity index 93% rename from vst/GUIComponents.cpp rename to editor/src/editor/GUIComponents.cpp index 314ba642..56fb6f8e 100644 --- a/vst/GUIComponents.cpp +++ b/editor/src/editor/GUIComponents.cpp @@ -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) diff --git a/vst/GUIComponents.h b/editor/src/editor/GUIComponents.h similarity index 91% rename from vst/GUIComponents.h rename to editor/src/editor/GUIComponents.h index 003d219b..c76c2e44 100644 --- a/vst/GUIComponents.h +++ b/editor/src/editor/GUIComponents.h @@ -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; diff --git a/editor/src/editor/utility/vstgui_after.h b/editor/src/editor/utility/vstgui_after.h new file mode 100644 index 00000000..69e3b4db --- /dev/null +++ b/editor/src/editor/utility/vstgui_after.h @@ -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 diff --git a/editor/src/editor/utility/vstgui_before.h b/editor/src/editor/utility/vstgui_before.h new file mode 100644 index 00000000..bb01d0c3 --- /dev/null +++ b/editor/src/editor/utility/vstgui_before.h @@ -0,0 +1,12 @@ +// 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" +#endif diff --git a/lv2/CMakeLists.txt b/lv2/CMakeLists.txt index 73de6ee5..4104eb25 100644 --- a/lv2/CMakeLists.txt +++ b/lv2/CMakeLists.txt @@ -45,7 +45,7 @@ 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) 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() diff --git a/vst/CMakeLists.txt b/vst/CMakeLists.txt index 0c14922d..5d0301e6 100644 --- a/vst/CMakeLists.txt +++ b/vst/CMakeLists.txt @@ -17,7 +17,6 @@ set(VSTPLUGIN_SOURCES SfizzVstController.cpp SfizzVstEditor.cpp SfizzVstState.cpp - GUIComponents.cpp VstPluginFactory.cpp X11RunLoop.cpp) @@ -26,7 +25,6 @@ set(VSTPLUGIN_HEADERS SfizzVstController.h SfizzVstEditor.h SfizzVstState.h - GUIComponents.h X11RunLoop.h) set(VSTPLUGIN_RESOURCES @@ -40,7 +38,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 diff --git a/vst/SfizzVstController.cpp b/vst/SfizzVstController.cpp index 8f13bab2..35eba7a0 100644 --- a/vst/SfizzVstController.cpp +++ b/vst/SfizzVstController.cpp @@ -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(); diff --git a/vst/SfizzVstEditor.cpp b/vst/SfizzVstEditor.cpp index 5863cdc5..163034cc 100644 --- a/vst/SfizzVstEditor.cpp +++ b/vst/SfizzVstEditor.cpp @@ -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(value)); - break; - - case kTagSetOversampling: - controller->setParamNormalized(kPidOversampling, valueNorm); - controller->performEdit(kPidOversampling, valueNorm); - updateOversamplingLabel(static_cast(value)); - break; - - case kTagSetPreloadSize: - controller->setParamNormalized(kPidPreloadSize, valueNorm); - controller->performEdit(kPidPreloadSize, valueNorm); - updatePreloadSizeLabel(static_cast(value)); - break; - - case kTagSetScalaRootKey: - controller->setParamNormalized(kPidScalaRootKey, valueNorm); - controller->performEdit(kPidScalaRootKey, valueNorm); - updateScalaRootKeyLabel(static_cast(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 fs(CNewFileSelector::create(frame)); + if (id == EditId::SfzFile) + loadSfzFile(absl::get(v)); + else if (id == EditId::ScalaFile) + loadScalaFile(absl::get(v)); + 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, absl::get(v)); + break; + case EditId::Polyphony: + normalizeAndSet(kPidNumVoices, kParamNumVoicesRange, absl::get(v)); + break; + case EditId::Oversampling: + { + const int32 value = static_cast(absl::get(v)); + + int32 log2Value = 0; + for (int32 f = value; f > 1; f /= 2) + ++log2Value; + + normalizeAndSet(kPidOversampling, kParamOversamplingRange, log2Value); + } + break; + case EditId::PreloadSize: + normalizeAndSet(kPidPreloadSize, kParamPreloadSizeRange, absl::get(v)); + break; + case EditId::ScalaRootKey: + normalizeAndSet(kPidScalaRootKey, kParamScalaRootKeyRange, absl::get(v)); + break; + case EditId::TuningFrequency: + normalizeAndSet(kPidTuningFrequency, kParamTuningFrequencyRange, absl::get(v)); + break; + case EditId::StretchTuning: + normalizeAndSet(kPidStretchedTuning, kParamStretchedTuningRange, absl::get(v)); + break; + + case EditId::UIActivePanel: + ctrl->getSfizzUiState().activePanel = static_cast(absl::get(v)); + 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 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(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 = ""; - 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(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; } } diff --git a/vst/SfizzVstEditor.h b/vst/SfizzVstEditor.h index 21cf8a87..9c918765 100644 --- a/vst/SfizzVstEditor.h +++ b/vst/SfizzVstEditor.h @@ -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(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 - void adjustMinMaxToRangeParam(Control* c, Vst::ParamID id) - { - auto* p = static_cast(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_; #if !defined(__APPLE__) && !defined(_WIN32) SharedPointer _runLoop; diff --git a/vst/SfizzVstProcessor.cpp b/vst/SfizzVstProcessor.cpp index bedde084..441fd9df 100644 --- a/vst/SfizzVstProcessor.cpp +++ b/vst/SfizzVstProcessor.cpp @@ -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(kParamScalaRootKey.denormalize(value)); + _state.scalaRootKey = static_cast(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; } } diff --git a/vst/SfizzVstState.h b/vst/SfizzVstState.h index f356d04e..531e2dac 100644 --- a/vst/SfizzVstState.h +++ b/vst/SfizzVstState.h @@ -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); diff --git a/vst/cmake/Vst3.cmake b/vst/cmake/Vst3.cmake index 68118f73..259f62a2 100644 --- a/vst/cmake/Vst3.cmake +++ b/vst/cmake/Vst3.cmake @@ -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()