Separate the editor code from VST

This commit is contained in:
Jean Pierre Cimalando 2020-08-29 04:54:18 +02:00
parent e2a0c521c3
commit e2b8b21967
29 changed files with 1557 additions and 1062 deletions

2
.gitmodules vendored
View file

@ -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

View file

@ -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:

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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 \
..

View file

@ -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()

View file

@ -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}]")

View file

@ -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}

16
editor/CMakeLists.txt Normal file
View file

@ -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)

209
editor/cmake/Vstgui.cmake Normal file
View file

@ -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()

View file

@ -0,0 +1,32 @@
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#include "EditIds.h"
EditRange EditRange::get(EditId id)
{
switch (id) {
default:
assert(false);
return {};
case EditId::Volume:
return { 0, -60, 6 };
case EditId::Polyphony:
return { 64, 1, 256 };
case EditId::Oversampling:
return { 0, 0, 3 };
case EditId::PreloadSize:
return { 8192, 1024, 65536 };
case EditId::ScalaRootKey:
return { 60, 0, 127 };
case EditId::TuningFrequency:
return { 440, 300, 500 };
case EditId::StretchTuning:
return { 0, 0, 1 };
case EditId::UIActivePanel:
return { 0, 0, 255 };
}
}

View file

@ -0,0 +1,37 @@
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#pragma once
#include <cassert>
enum class EditId : int {
SfzFile,
Volume,
Polyphony,
Oversampling,
PreloadSize,
ScalaFile,
ScalaRootKey,
TuningFrequency,
StretchTuning,
UINumCurves,
UINumMasters,
UINumGroups,
UINumRegions,
UINumPreloadedSamples,
UINumActiveVoices,
UIActivePanel,
};
struct EditRange {
float def = 0.0;
float min = 0.0;
float max = 1.0;
constexpr EditRange() = default;
constexpr EditRange(float def, float min, float max)
: def(def), min(min), max(max) {}
static EditRange get(EditId id);
};

View file

@ -0,0 +1,977 @@
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#include "Editor.h"
#include "EditorController.h"
#include "EditIds.h"
#include "GUIComponents.h"
#include <absl/strings/string_view.h>
#include <cstdarg>
#include <cstdio>
#include "utility/vstgui_before.h"
#include "vstgui/vstgui.h"
#include "utility/vstgui_after.h"
using namespace VSTGUI;
const int Editor::viewWidth { 482 };
const int Editor::viewHeight { 225 };
struct Editor::Impl : EditorController::Receiver, IControlListener {
EditorController* ctrl_ = nullptr;
CFrame* frame_ = nullptr;
SharedPointer<CViewContainer> view_;
enum {
kPanelGeneral,
// kPanelControls,
kPanelSettings,
kPanelTuning,
kPanelInfo,
kNumPanels,
};
unsigned activePanel_ = 0;
CViewContainer* subPanels_[kNumPanels] = {};
enum {
kTagLoadSfzFile,
kTagSetVolume,
kTagSetNumVoices,
kTagSetOversampling,
kTagSetPreloadSize,
kTagLoadScalaFile,
kTagSetScalaRootKey,
kTagSetTuningFrequency,
kTagSetStretchedTuning,
kTagFirstChangePanel,
kTagLastChangePanel = kTagFirstChangePanel + kNumPanels - 1,
};
CTextLabel* sfzFileLabel_ = nullptr;
CTextLabel* scalaFileLabel_ = nullptr;
CSliderBase *volumeSlider_ = nullptr;
CTextLabel* volumeLabel_ = nullptr;
CSliderBase *numVoicesSlider_ = nullptr;
CTextLabel* numVoicesLabel_ = nullptr;
CSliderBase *oversamplingSlider_ = nullptr;
CTextLabel* oversamplingLabel_ = nullptr;
CSliderBase *preloadSizeSlider_ = nullptr;
CTextLabel* preloadSizeLabel_ = nullptr;
CSliderBase *scalaRootKeySlider_ = nullptr;
CTextLabel* scalaRootKeyLabel_ = nullptr;
CSliderBase *tuningFrequencySlider_ = nullptr;
CTextLabel* tuningFrequencyLabel_ = nullptr;
CSliderBase *stretchedTuningSlider_ = nullptr;
CTextLabel* stretchedTuningLabel_ = nullptr;
CTextLabel* infoCurvesLabel_ = nullptr;
CTextLabel* infoMastersLabel_ = nullptr;
CTextLabel* infoGroupsLabel_ = nullptr;
CTextLabel* infoRegionsLabel_ = nullptr;
CTextLabel* infoSamplesLabel_ = nullptr;
CTextLabel* infoVoicesLabel_ = nullptr;
void uiReceiveValue(EditId id, const EditValue& v) override;
void createFrameContents();
template <class Control>
void adjustMinMaxToEditRange(Control* c, EditId id)
{
const EditRange er = EditRange::get(id);
c->setMin(er.min);
c->setMax(er.max);
c->setDefaultValue(er.def);
}
void chooseSfzFile();
void chooseScalaFile();
void updateSfzFileLabel(const std::string& filePath);
void updateScalaFileLabel(const std::string& filePath);
static void updateLabelWithFileName(CTextLabel* label, const std::string& filePath);
void updateVolumeLabel(float volume);
void updateNumVoicesLabel(int numVoices);
void updateOversamplingLabel(int oversamplingLog2);
void updatePreloadSizeLabel(int preloadSize);
void updateScalaRootKeyLabel(int rootKey);
void updateTuningFrequencyLabel(float tuningFrequency);
void updateStretchedTuningLabel(float stretchedTuning);
void setActivePanel(unsigned panelId);
static void formatLabel(CTextLabel* label, const char* fmt, ...);
static void vformatLabel(CTextLabel* label, const char* fmt, va_list ap);
// IControlListener
void valueChanged(CControl* ctl) override;
void enterOrLeaveEdit(CControl* ctl, bool enter);
void controlBeginEdit(CControl* ctl) override;
void controlEndEdit(CControl* ctl) override;
};
Editor::Editor(EditorController& ctrl)
: impl_(new Impl)
{
Impl& impl = *impl_;
impl.ctrl_ = &ctrl;
ctrl.decorate(&impl);
impl.createFrameContents();
}
Editor::~Editor()
{
Impl& impl = *impl_;
EditorController& ctrl = *impl.ctrl_;
ctrl.decorate(nullptr);
}
void Editor::open(CFrame& frame)
{
Impl& impl = *impl_;
impl.frame_ = &frame;
frame.addView(impl.view_.get());
}
void Editor::close()
{
Impl& impl = *impl_;
if (impl.frame_) {
impl.frame_->removeView(impl.view_.get());
impl.frame_ = nullptr;
}
}
void Editor::Impl::uiReceiveValue(EditId id, const EditValue& v)
{
switch (id) {
case EditId::SfzFile:
{
const std::string& value = absl::get<std::string>(v);
updateSfzFileLabel(value);
}
break;
case EditId::Volume:
{
const float value = absl::get<float>(v);
if (volumeSlider_)
volumeSlider_->setValue(value);
updateVolumeLabel(value);
}
break;
case EditId::Polyphony:
{
const int value = static_cast<int>(absl::get<float>(v));
if (numVoicesSlider_)
numVoicesSlider_->setValue(value);
updateNumVoicesLabel(value);
}
break;
case EditId::Oversampling:
{
const int value = static_cast<int>(absl::get<float>(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<int>(absl::get<float>(v));
if (preloadSizeSlider_)
preloadSizeSlider_->setValue(value);
updatePreloadSizeLabel(value);
}
break;
case EditId::ScalaFile:
{
const std::string& value = absl::get<std::string>(v);
updateScalaFileLabel(value);
}
break;
case EditId::ScalaRootKey:
{
const int value = static_cast<int>(absl::get<float>(v));
if (scalaRootKeySlider_)
scalaRootKeySlider_->setValue(value);
updateScalaRootKeyLabel(value);
}
break;
case EditId::TuningFrequency:
{
const float value = absl::get<float>(v);
if (tuningFrequencySlider_)
tuningFrequencySlider_->setValue(value);
updateTuningFrequencyLabel(value);
}
break;
case EditId::StretchTuning:
{
const float value = absl::get<float>(v);
if (stretchedTuningSlider_)
stretchedTuningSlider_->setValue(value);
updateStretchedTuningLabel(value);
}
break;
case EditId::UINumCurves:
{
const int value = static_cast<int>(absl::get<float>(v));
if (CTextLabel* label = infoCurvesLabel_)
formatLabel(label, "%u", value);
}
break;
case EditId::UINumMasters:
{
const int value = static_cast<int>(absl::get<float>(v));
if (CTextLabel* label = infoMastersLabel_)
formatLabel(label, "%u", value);
}
break;
case EditId::UINumGroups:
{
const int value = static_cast<int>(absl::get<float>(v));
if (CTextLabel* label = infoGroupsLabel_)
formatLabel(label, "%u", value);
}
break;
case EditId::UINumRegions:
{
const int value = static_cast<int>(absl::get<float>(v));
if (CTextLabel* label = infoRegionsLabel_)
formatLabel(label, "%u", value);
}
break;
case EditId::UINumPreloadedSamples:
{
const int value = static_cast<int>(absl::get<float>(v));
if (CTextLabel* label = infoSamplesLabel_)
formatLabel(label, "%u", value);
}
break;
case EditId::UINumActiveVoices:
{
const int value = static_cast<int>(absl::get<float>(v));
if (CTextLabel* label = infoVoicesLabel_)
formatLabel(label, "%u", value);
}
break;
case EditId::UIActivePanel:
{
const int value = static_cast<int>(absl::get<float>(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<CBitmap> logo = new CBitmap("logo.png");
CRect bottomRow = bounds;
bottomRow.top = bottomRow.bottom - 30;
CRect topRow = bounds;
topRow.bottom = topRow.top + 30;
CViewContainer* panel;
activePanel_ = 0;
CRect topLeftLabelBox = topRow;
topLeftLabelBox.right -= 20 * kNumPanels;
// general panel
{
panel = new CViewContainer(bounds);
view->addView(panel);
panel->setTransparency(true);
CKickButton* sfizzButton = new CKickButton(bounds, this, kTagLoadSfzFile, logo);
panel->addView(sfizzButton);
CTextLabel* topLeftLabel = new CTextLabel(topLeftLabelBox, "No file loaded");
topLeftLabel->setFontColor(CColor(0x00, 0x00, 0x00));
topLeftLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
panel->addView(topLeftLabel);
sfzFileLabel_ = topLeftLabel;
subPanels_[kPanelGeneral] = panel;
}
// settings panel
{
panel = new CViewContainer(bounds);
view->addView(panel);
panel->setTransparency(true);
CTextLabel* topLeftLabel = new CTextLabel(topLeftLabelBox, "Settings");
topLeftLabel->setFontColor(CColor(0x00, 0x00, 0x00));
topLeftLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
panel->addView(topLeftLabel);
CRect row = topRow;
row.top += 45.0;
row.bottom += 45.0;
row.left += 20.0;
row.right -= 20.0;
static const CCoord interRow = 35.0;
static const CCoord interColumn = 20.0;
static const int numColumns = 3;
auto nthColumn = [&row](int colIndex) -> CRect {
CRect div = row;
CCoord columnWidth = (div.right - div.left + interColumn) / numColumns - interColumn;
div.left = div.left + colIndex * (columnWidth + interColumn);
div.right = div.left + columnWidth;
return div;
};
CTextLabel* label;
SimpleSlider* slider;
label = new CTextLabel(nthColumn(0), "Volume");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
slider = new SimpleSlider(nthColumn(1), this, kTagSetVolume);
panel->addView(slider);
adjustMinMaxToEditRange(slider, EditId::Volume);
volumeSlider_ = slider;
label = new CTextLabel(nthColumn(2), "");
volumeLabel_ = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Polyphony");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
slider = new SimpleSlider(nthColumn(1), this, kTagSetNumVoices);
panel->addView(slider);
adjustMinMaxToEditRange(slider, EditId::Polyphony);
numVoicesSlider_ = slider;
label = new CTextLabel(nthColumn(2), "");
numVoicesLabel_ = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Oversampling");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
slider = new SimpleSlider(nthColumn(1), this, kTagSetOversampling);
panel->addView(slider);
adjustMinMaxToEditRange(slider, EditId::Oversampling);
oversamplingSlider_ = slider;
label = new CTextLabel(nthColumn(2), "");
oversamplingLabel_ = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Preload size");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
slider = new SimpleSlider(nthColumn(1), this, kTagSetPreloadSize);
panel->addView(slider);
adjustMinMaxToEditRange(slider, EditId::PreloadSize);
preloadSizeSlider_ = slider;
label = new CTextLabel(nthColumn(2), "");
preloadSizeLabel_ = label;
panel->addView(label);
subPanels_[kPanelSettings] = panel;
}
// tuning panel
{
panel = new CViewContainer(bounds);
view->addView(panel);
panel->setTransparency(true);
CTextLabel* topLeftLabel = new CTextLabel(topLeftLabelBox, "Tuning");
topLeftLabel->setFontColor(CColor(0x00, 0x00, 0x00));
topLeftLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
panel->addView(topLeftLabel);
CRect row = topRow;
row.top += 45.0;
row.bottom += 45.0;
row.left += 20.0;
row.right -= 20.0;
static const CCoord interRow = 35.0;
static const CCoord interColumn = 20.0;
static const int numColumns = 3;
auto nthColumn = [&row](int colIndex) -> CRect {
CRect div = row;
CCoord columnWidth = (div.right - div.left + interColumn) / numColumns - interColumn;
div.left = div.left + colIndex * (columnWidth + interColumn);
div.right = div.left + columnWidth;
return div;
};
CTextLabel* label;
SimpleSlider* slider;
CTextButton* textbutton;
label = new CTextLabel(nthColumn(0), "Scala file");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
textbutton = new CTextButton(nthColumn(1), this, kTagLoadScalaFile, "Choose");
panel->addView(textbutton);
label = new CTextLabel(nthColumn(2), "");
scalaFileLabel_ = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Scala root key");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
slider = new SimpleSlider(nthColumn(1), this, kTagSetScalaRootKey);
panel->addView(slider);
adjustMinMaxToEditRange(slider, EditId::ScalaRootKey);
scalaRootKeySlider_ = slider;
label = new CTextLabel(nthColumn(2), "");
scalaRootKeyLabel_ = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Tuning frequency");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
slider = new SimpleSlider(nthColumn(1), this, kTagSetTuningFrequency);
panel->addView(slider);
adjustMinMaxToEditRange(slider, EditId::TuningFrequency);
tuningFrequencySlider_ = slider;
label = new CTextLabel(nthColumn(2), "");
tuningFrequencyLabel_ = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Stretched tuning");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
slider = new SimpleSlider(nthColumn(1), this, kTagSetStretchedTuning);
panel->addView(slider);
adjustMinMaxToEditRange(slider, EditId::StretchTuning);
stretchedTuningSlider_ = slider;
label = new CTextLabel(nthColumn(2), "");
stretchedTuningLabel_ = label;
panel->addView(label);
subPanels_[kPanelTuning] = panel;
}
// info panel
{
panel = new CViewContainer(bounds);
view->addView(panel);
panel->setTransparency(true);
CTextLabel* topLeftLabel = new CTextLabel(topLeftLabelBox, "Information");
topLeftLabel->setFontColor(CColor(0x00, 0x00, 0x00));
topLeftLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
panel->addView(topLeftLabel);
CRect row = topRow;
row.top += 45.0;
row.bottom += 45.0;
row.left += 20.0;
row.right -= 20.0;
static const CCoord interRow = 20.0;
static const CCoord interColumn = 20.0;
static const int numColumns = 3;
auto nthColumn = [&row](int colIndex) -> CRect {
CRect div = row;
CCoord columnWidth = (div.right - div.left + interColumn) / numColumns - interColumn;
div.left = div.left + colIndex * (columnWidth + interColumn);
div.right = div.left + columnWidth;
return div;
};
CTextLabel* label;
label = new CTextLabel(nthColumn(0), "Curves");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
label = new CTextLabel(nthColumn(1), "");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
infoCurvesLabel_ = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Masters");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
label = new CTextLabel(nthColumn(1), "");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
infoMastersLabel_ = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Groups");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
label = new CTextLabel(nthColumn(1), "");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
infoGroupsLabel_ = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Regions");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
label = new CTextLabel(nthColumn(1), "");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
infoRegionsLabel_ = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Samples");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
label = new CTextLabel(nthColumn(1), "");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
infoSamplesLabel_ = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Voices");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
label = new CTextLabel(nthColumn(1), "");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
infoVoicesLabel_ = label;
panel->addView(label);
subPanels_[kPanelInfo] = panel;
}
// all panels
for (unsigned currentPanel = 0; currentPanel < kNumPanels; ++currentPanel) {
panel = subPanels_[currentPanel];
CTextLabel* descLabel = new CTextLabel(
bottomRow, "Paul Ferrand and the SFZ Tools work group");
descLabel->setFontColor(CColor(0x00, 0x00, 0x00));
descLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
panel->addView(descLabel);
for (unsigned i = 0; i < kNumPanels; ++i) {
CRect btnRect = topRow;
btnRect.left = topRow.right - (kNumPanels - i) * 50;
btnRect.right = btnRect.left + 50;
const char *text;
switch (i) {
case kPanelGeneral: text = "File"; break;
case kPanelSettings: text = "Setup"; break;
case kPanelTuning: text = "Tuning"; break;
case kPanelInfo: text = "Info"; break;
default: text = "?"; break;
}
CTextButton* changePanelButton = new CTextButton(btnRect, this, kTagFirstChangePanel + i, text);
panel->addView(changePanelButton);
changePanelButton->setRoundRadius(0.0);
}
panel->setVisible(currentPanel == activePanel_);
}
}
void Editor::Impl::chooseSfzFile()
{
SharedPointer<CNewFileSelector> fs(CNewFileSelector::create(frame_));
fs->setTitle("Load SFZ file");
fs->setDefaultExtension(CFileExtension("SFZ", "sfz"));
if (fs->runModal()) {
UTF8StringPtr file = fs->getSelectedFile(0);
if (file) {
std::string str(file);
ctrl_->uiSendValue(EditId::SfzFile, str);
updateSfzFileLabel(str);
}
}
}
void Editor::Impl::chooseScalaFile()
{
SharedPointer<CNewFileSelector> fs(CNewFileSelector::create(frame_));
fs->setTitle("Load Scala file");
fs->setDefaultExtension(CFileExtension("SCL", "scl"));
if (fs->runModal()) {
UTF8StringPtr file = fs->getSelectedFile(0);
if (file) {
std::string str(file);
ctrl_->uiSendValue(EditId::ScalaFile, str);
updateScalaFileLabel(str);
}
}
}
void Editor::Impl::updateSfzFileLabel(const std::string& filePath)
{
updateLabelWithFileName(sfzFileLabel_, filePath);
}
void Editor::Impl::updateScalaFileLabel(const std::string& filePath)
{
updateLabelWithFileName(scalaFileLabel_, filePath);
}
void Editor::Impl::updateLabelWithFileName(CTextLabel* label, const std::string& filePath)
{
if (!label)
return;
std::string fileName;
if (filePath.empty())
fileName = "<No file>";
else {
#if defined (_WIN32)
size_t pos = filePath.find_last_of("/\\");
#else
size_t pos = filePath.rfind('/');
#endif
fileName = (pos != filePath.npos) ?
filePath.substr(pos + 1) : filePath;
}
label->setText(fileName.c_str());
}
void Editor::Impl::updateVolumeLabel(float volume)
{
CTextLabel* label = volumeLabel_;
if (!label)
return;
char text[64];
sprintf(text, "%.1f dB", volume);
text[sizeof(text) - 1] = '\0';
label->setText(text);
}
void Editor::Impl::updateNumVoicesLabel(int numVoices)
{
CTextLabel* label = numVoicesLabel_;
if (!label)
return;
char text[64];
sprintf(text, "%d", numVoices);
text[sizeof(text) - 1] = '\0';
label->setText(text);
}
void Editor::Impl::updateOversamplingLabel(int oversamplingLog2)
{
CTextLabel* label = oversamplingLabel_;
if (!label)
return;
char text[64];
sprintf(text, "%dx", 1 << oversamplingLog2);
text[sizeof(text) - 1] = '\0';
label->setText(text);
}
void Editor::Impl::updatePreloadSizeLabel(int preloadSize)
{
CTextLabel* label = preloadSizeLabel_;
if (!label)
return;
char text[64];
sprintf(text, "%.1f kB", preloadSize * (1.0 / 1024));
text[sizeof(text) - 1] = '\0';
label->setText(text);
}
void Editor::Impl::updateScalaRootKeyLabel(int rootKey)
{
CTextLabel* label = scalaRootKeyLabel_;
if (!label)
return;
static const char *octNoteNames[12] = {
"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B",
};
auto noteName = [](int key) -> std::string
{
int octNum;
int octNoteNum;
if (key >= 0) {
octNum = key / 12 - 1;
octNoteNum = key % 12;
}
else {
octNum = -2 - (key + 1) / -12;
octNoteNum = (key % 12 + 12) % 12;
}
return std::string(octNoteNames[octNoteNum]) + std::to_string(octNum);
};
label->setText(noteName(rootKey));
}
void Editor::Impl::updateTuningFrequencyLabel(float tuningFrequency)
{
CTextLabel* label = tuningFrequencyLabel_;
if (!label)
return;
char text[64];
sprintf(text, "%.1f", tuningFrequency);
text[sizeof(text) - 1] = '\0';
label->setText(text);
}
void Editor::Impl::updateStretchedTuningLabel(float stretchedTuning)
{
CTextLabel* label = stretchedTuningLabel_;
if (!label)
return;
char text[64];
sprintf(text, "%.3f", stretchedTuning);
text[sizeof(text) - 1] = '\0';
label->setText(text);
}
void Editor::Impl::setActivePanel(unsigned panelId)
{
panelId = std::max(0, std::min(kNumPanels - 1, static_cast<int>(panelId)));
if (activePanel_ != panelId) {
subPanels_[activePanel_]->setVisible(false);
activePanel_ = panelId;
subPanels_[panelId]->setVisible(true);
}
}
void Editor::Impl::formatLabel(CTextLabel* label, const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vformatLabel(label, fmt, ap);
va_end(ap);
}
void Editor::Impl::vformatLabel(CTextLabel* label, const char* fmt, va_list ap)
{
char text[256];
vsprintf(text, fmt, ap);
text[sizeof(text) - 1] = '\0';
label->setText(text);
}
void Editor::Impl::valueChanged(CControl* ctl)
{
int32_t tag = ctl->getTag();
float value = ctl->getValue();
EditorController& ctrl = *ctrl_;
switch (tag) {
case kTagLoadSfzFile:
if (value != 1)
break;
Call::later([this]() { chooseSfzFile(); });
break;
case kTagLoadScalaFile:
if (value != 1)
break;
Call::later([this]() { chooseScalaFile(); });
break;
case kTagSetVolume:
ctrl.uiSendValue(EditId::Volume, value);
updateVolumeLabel(value);
break;
case kTagSetNumVoices:
ctrl.uiSendValue(EditId::Polyphony, value);
updateNumVoicesLabel(static_cast<int>(value));
break;
case kTagSetOversampling:
ctrl.uiSendValue(EditId::Oversampling, 1 << static_cast<int>(value));
updateOversamplingLabel(static_cast<int>(value));
break;
case kTagSetPreloadSize:
ctrl.uiSendValue(EditId::PreloadSize, value);
updatePreloadSizeLabel(static_cast<int>(value));
break;
case kTagSetScalaRootKey:
ctrl.uiSendValue(EditId::ScalaRootKey, value);
updateScalaRootKeyLabel(static_cast<int>(value));
break;
case kTagSetTuningFrequency:
ctrl.uiSendValue(EditId::TuningFrequency, value);
updateTuningFrequencyLabel(value);
break;
case kTagSetStretchedTuning:
ctrl.uiSendValue(EditId::StretchTuning, value);
updateStretchedTuningLabel(value);
break;
default:
if (tag >= kTagFirstChangePanel && tag <= kTagLastChangePanel) {
int panelId = tag - kTagFirstChangePanel;
ctrl.uiSendValue(EditId::UIActivePanel, 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);
}

View file

@ -0,0 +1,30 @@
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#pragma once
#include <memory>
class EditorController;
#include "utility/vstgui_before.h"
#include "vstgui/lib/vstguifwd.h"
#include "utility/vstgui_after.h"
using VSTGUI::CFrame;
class Editor {
public:
static const int viewWidth;
static const int viewHeight;
explicit Editor(EditorController& ctrl);
~Editor();
void open(CFrame& frame);
void close();
private:
struct Impl;
std::unique_ptr<Impl> impl_;
};

View file

@ -0,0 +1,43 @@
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#pragma once
#include <absl/strings/string_view.h>
#include <absl/types/variant.h>
#include <cstdint>
enum class EditId : int;
typedef absl::variant<float, std::string> 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);
}

View file

@ -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)

View file

@ -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;

View file

@ -0,0 +1,9 @@
// SPDX-License-Identifier: BSD-2-Clause
// This code is part of the sfizz library and is licensed under a BSD 2-clause
// license. You should have receive a LICENSE.md file along with the code.
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif

View file

@ -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

View file

@ -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()

View file

@ -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

View file

@ -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();

View file

@ -6,18 +6,18 @@
#include "SfizzVstEditor.h"
#include "SfizzVstState.h"
#include "GUIComponents.h"
#include "editor/Editor.h"
#include "editor/EditIds.h"
#if !defined(__APPLE__) && !defined(_WIN32)
#include "X11RunLoop.h"
#endif
using namespace VSTGUI;
static ViewRect sfizzUiViewRect {0, 0, 482, 225};
static ViewRect sfizzUiViewRect { 0, 0, Editor::viewWidth, Editor::viewHeight };
SfizzVstEditor::SfizzVstEditor(void *controller)
: VSTGUIEditor(controller, &sfizzUiViewRect),
_logo("logo.png")
: VSTGUIEditor(controller, &sfizzUiViewRect)
{
getController()->addSfizzStateListener(this);
}
@ -45,7 +45,11 @@ bool PLUGIN_API SfizzVstEditor::open(void* parent, const VSTGUI::PlatformType& p
config = &x11config;
#endif
createFrameContents();
Editor* editor = editor_.get();
if (!editor) {
editor = new Editor(*this);
editor_.reset(editor);
}
updateStateDisplay();
if (!frame->open(parent, platformType, config)) {
@ -53,6 +57,8 @@ bool PLUGIN_API SfizzVstEditor::open(void* parent, const VSTGUI::PlatformType& p
return false;
}
editor->open(*frame);
return true;
}
@ -60,121 +66,16 @@ void PLUGIN_API SfizzVstEditor::close()
{
CFrame *frame = this->frame;
if (frame) {
frame->removeAll();
if (editor_)
editor_->close();
if (frame->getNbReference() != 1)
frame->forget ();
else {
frame->forget();
else
frame->close();
this->frame = nullptr;
}
}
}
///
void SfizzVstEditor::valueChanged(CControl* ctl)
{
int32_t tag = ctl->getTag();
float value = ctl->getValue();
float valueNorm = ctl->getValueNormalized();
SfizzVstController* controller = getController();
switch (tag) {
case kTagLoadSfzFile:
if (value != 1)
break;
Call::later([this]() { chooseSfzFile(); });
break;
case kTagLoadScalaFile:
if (value != 1)
break;
Call::later([this]() { chooseScalaFile(); });
break;
case kTagSetVolume:
controller->setParamNormalized(kPidVolume, valueNorm);
controller->performEdit(kPidVolume, valueNorm);
updateVolumeLabel(value);
break;
case kTagSetNumVoices:
controller->setParamNormalized(kPidNumVoices, valueNorm);
controller->performEdit(kPidNumVoices, valueNorm);
updateNumVoicesLabel(static_cast<int>(value));
break;
case kTagSetOversampling:
controller->setParamNormalized(kPidOversampling, valueNorm);
controller->performEdit(kPidOversampling, valueNorm);
updateOversamplingLabel(static_cast<int>(value));
break;
case kTagSetPreloadSize:
controller->setParamNormalized(kPidPreloadSize, valueNorm);
controller->performEdit(kPidPreloadSize, valueNorm);
updatePreloadSizeLabel(static_cast<int>(value));
break;
case kTagSetScalaRootKey:
controller->setParamNormalized(kPidScalaRootKey, valueNorm);
controller->performEdit(kPidScalaRootKey, valueNorm);
updateScalaRootKeyLabel(static_cast<int>(value));
break;
case kTagSetTuningFrequency:
controller->setParamNormalized(kPidTuningFrequency, valueNorm);
controller->performEdit(kPidTuningFrequency, valueNorm);
updateTuningFrequencyLabel(value);
break;
case kTagSetStretchedTuning:
controller->setParamNormalized(kPidStretchedTuning, valueNorm);
controller->performEdit(kPidStretchedTuning, valueNorm);
updateStretchedTuningLabel(value);
break;
default:
if (tag >= kTagFirstChangePanel && tag <= kTagLastChangePanel)
setActivePanel(tag - kTagFirstChangePanel);
break;
}
}
void SfizzVstEditor::enterOrLeaveEdit(CControl* ctl, bool enter)
{
int32_t tag = ctl->getTag();
Vst::ParamID id;
switch (tag) {
case kTagSetVolume: id = kPidVolume; break;
case kTagSetNumVoices: id = kPidNumVoices; break;
case kTagSetOversampling: id = kPidOversampling; break;
case kTagSetPreloadSize: id = kPidPreloadSize; break;
case kTagSetScalaRootKey: id = kPidScalaRootKey; break;
case kTagSetTuningFrequency: id = kPidTuningFrequency; break;
case kTagSetStretchedTuning: id = kPidStretchedTuning; break;
default: return;
}
SfizzVstController* controller = getController();
if (enter)
controller->beginEdit(id);
else
controller->endEdit(id);
}
void SfizzVstEditor::controlBeginEdit(CControl* ctl)
{
enterOrLeaveEdit(ctl, true);
}
void SfizzVstEditor::controlEndEdit(CControl* ctl)
{
enterOrLeaveEdit(ctl, false);
}
CMessageResult SfizzVstEditor::notify(CBaseObject* sender, const char* message)
{
CMessageResult result = VSTGUIEditor::notify(sender, message);
@ -205,20 +106,83 @@ void SfizzVstEditor::onStateChanged()
}
///
void SfizzVstEditor::chooseSfzFile()
void SfizzVstEditor::uiSendValue(EditId id, const EditValue& v)
{
SharedPointer<CNewFileSelector> fs(CNewFileSelector::create(frame));
if (id == EditId::SfzFile)
loadSfzFile(absl::get<std::string>(v));
else if (id == EditId::ScalaFile)
loadScalaFile(absl::get<std::string>(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<float>(v));
break;
case EditId::Polyphony:
normalizeAndSet(kPidNumVoices, kParamNumVoicesRange, absl::get<float>(v));
break;
case EditId::Oversampling:
{
const int32 value = static_cast<int32>(absl::get<float>(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<float>(v));
break;
case EditId::ScalaRootKey:
normalizeAndSet(kPidScalaRootKey, kParamScalaRootKeyRange, absl::get<float>(v));
break;
case EditId::TuningFrequency:
normalizeAndSet(kPidTuningFrequency, kParamTuningFrequencyRange, absl::get<float>(v));
break;
case EditId::StretchTuning:
normalizeAndSet(kPidStretchedTuning, kParamStretchedTuningRange, absl::get<float>(v));
break;
case EditId::UIActivePanel:
ctrl->getSfizzUiState().activePanel = static_cast<int32>(absl::get<float>(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<CNewFileSelector> fs(CNewFileSelector::create(frame));
fs->setTitle("Load Scala file");
fs->setDefaultExtension(CFileExtension("SCL", "scl"));
if (fs->runModal()) {
UTF8StringPtr file = fs->getSelectedFile(0);
if (file)
loadScalaFile(file);
}
}
void SfizzVstEditor::loadScalaFile(const std::string& filePath)
@ -265,414 +213,6 @@ void SfizzVstEditor::loadScalaFile(const std::string& filePath)
Vst::IAttributeList* attr = msg->getAttributes();
attr->setBinary("File", filePath.data(), filePath.size());
ctl->sendMessage(msg);
updateScalaFileLabel(filePath);
}
void SfizzVstEditor::createFrameContents()
{
SfizzVstController* controller = getController();
const SfizzUiState& uiState = controller->getSfizzUiState();
CFrame* frame = this->frame;
CRect bounds = frame->getViewSize();
frame->setBackgroundColor(CColor(0xff, 0xff, 0xff));
CRect bottomRow = bounds;
bottomRow.top = bottomRow.bottom - 30;
CRect topRow = bounds;
topRow.bottom = topRow.top + 30;
CViewContainer* panel;
_activePanel = std::max(0, std::min(kNumPanels - 1, static_cast<int>(uiState.activePanel)));
CRect topLeftLabelBox = topRow;
topLeftLabelBox.right -= 20 * kNumPanels;
// general panel
{
panel = new CViewContainer(bounds);
frame->addView(panel);
panel->setTransparency(true);
CKickButton* sfizzButton = new CKickButton(bounds, this, kTagLoadSfzFile, &_logo);
panel->addView(sfizzButton);
CTextLabel* topLeftLabel = new CTextLabel(topLeftLabelBox, "No file loaded");
topLeftLabel->setFontColor(CColor(0x00, 0x00, 0x00));
topLeftLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
panel->addView(topLeftLabel);
_sfzFileLabel = topLeftLabel;
_subPanels[kPanelGeneral] = panel;
}
// settings panel
{
panel = new CViewContainer(bounds);
frame->addView(panel);
panel->setTransparency(true);
CTextLabel* topLeftLabel = new CTextLabel(topLeftLabelBox, "Settings");
topLeftLabel->setFontColor(CColor(0x00, 0x00, 0x00));
topLeftLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
panel->addView(topLeftLabel);
CRect row = topRow;
row.top += 45.0;
row.bottom += 45.0;
row.left += 20.0;
row.right -= 20.0;
static const CCoord interRow = 35.0;
static const CCoord interColumn = 20.0;
static const int numColumns = 3;
auto nthColumn = [&row](int colIndex) -> CRect {
CRect div = row;
CCoord columnWidth = (div.right - div.left + interColumn) / numColumns - interColumn;
div.left = div.left + colIndex * (columnWidth + interColumn);
div.right = div.left + columnWidth;
return div;
};
CTextLabel* label;
SimpleSlider* slider;
label = new CTextLabel(nthColumn(0), "Volume");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
slider = new SimpleSlider(nthColumn(1), this, kTagSetVolume);
panel->addView(slider);
adjustMinMaxToRangeParam(slider, kPidVolume);
_volumeSlider = slider;
label = new CTextLabel(nthColumn(2), "");
_volumeLabel = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Polyphony");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
slider = new SimpleSlider(nthColumn(1), this, kTagSetNumVoices);
panel->addView(slider);
adjustMinMaxToRangeParam(slider, kPidNumVoices);
_numVoicesSlider = slider;
label = new CTextLabel(nthColumn(2), "");
_numVoicesLabel = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Oversampling");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
slider = new SimpleSlider(nthColumn(1), this, kTagSetOversampling);
panel->addView(slider);
adjustMinMaxToRangeParam(slider, kPidOversampling);
_oversamplingSlider = slider;
label = new CTextLabel(nthColumn(2), "");
_oversamplingLabel = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Preload size");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
slider = new SimpleSlider(nthColumn(1), this, kTagSetPreloadSize);
panel->addView(slider);
adjustMinMaxToRangeParam(slider, kPidPreloadSize);
_preloadSizeSlider = slider;
label = new CTextLabel(nthColumn(2), "");
_preloadSizeLabel = label;
panel->addView(label);
_subPanels[kPanelSettings] = panel;
}
// tuning panel
{
panel = new CViewContainer(bounds);
frame->addView(panel);
panel->setTransparency(true);
CTextLabel* topLeftLabel = new CTextLabel(topLeftLabelBox, "Tuning");
topLeftLabel->setFontColor(CColor(0x00, 0x00, 0x00));
topLeftLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
panel->addView(topLeftLabel);
CRect row = topRow;
row.top += 45.0;
row.bottom += 45.0;
row.left += 20.0;
row.right -= 20.0;
static const CCoord interRow = 35.0;
static const CCoord interColumn = 20.0;
static const int numColumns = 3;
auto nthColumn = [&row](int colIndex) -> CRect {
CRect div = row;
CCoord columnWidth = (div.right - div.left + interColumn) / numColumns - interColumn;
div.left = div.left + colIndex * (columnWidth + interColumn);
div.right = div.left + columnWidth;
return div;
};
CTextLabel* label;
SimpleSlider* slider;
CTextButton* textbutton;
label = new CTextLabel(nthColumn(0), "Scala file");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
textbutton = new CTextButton(nthColumn(1), this, kTagLoadScalaFile, "Choose");
panel->addView(textbutton);
label = new CTextLabel(nthColumn(2), "");
_scalaFileLabel = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Scala root key");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
slider = new SimpleSlider(nthColumn(1), this, kTagSetScalaRootKey);
panel->addView(slider);
adjustMinMaxToRangeParam(slider, kPidScalaRootKey);
_scalaRootKeySlider = slider;
label = new CTextLabel(nthColumn(2), "");
_scalaRootKeyLabel = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Tuning frequency");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
slider = new SimpleSlider(nthColumn(1), this, kTagSetTuningFrequency);
panel->addView(slider);
adjustMinMaxToRangeParam(slider, kPidTuningFrequency);
_tuningFrequencySlider = slider;
label = new CTextLabel(nthColumn(2), "");
_tuningFrequencyLabel = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Stretched tuning");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
slider = new SimpleSlider(nthColumn(1), this, kTagSetStretchedTuning);
panel->addView(slider);
adjustMinMaxToRangeParam(slider, kPidStretchedTuning);
_stretchedTuningSlider = slider;
label = new CTextLabel(nthColumn(2), "");
_stretchedTuningLabel = label;
panel->addView(label);
_subPanels[kPanelTuning] = panel;
}
// info panel
{
panel = new CViewContainer(bounds);
frame->addView(panel);
panel->setTransparency(true);
CTextLabel* topLeftLabel = new CTextLabel(topLeftLabelBox, "Information");
topLeftLabel->setFontColor(CColor(0x00, 0x00, 0x00));
topLeftLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
panel->addView(topLeftLabel);
CRect row = topRow;
row.top += 45.0;
row.bottom += 45.0;
row.left += 20.0;
row.right -= 20.0;
static const CCoord interRow = 20.0;
static const CCoord interColumn = 20.0;
static const int numColumns = 3;
auto nthColumn = [&row](int colIndex) -> CRect {
CRect div = row;
CCoord columnWidth = (div.right - div.left + interColumn) / numColumns - interColumn;
div.left = div.left + colIndex * (columnWidth + interColumn);
div.right = div.left + columnWidth;
return div;
};
CTextLabel* label;
label = new CTextLabel(nthColumn(0), "Curves");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
label = new CTextLabel(nthColumn(1), "");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
_infoCurvesLabel = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Masters");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
label = new CTextLabel(nthColumn(1), "");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
_infoMastersLabel = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Groups");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
label = new CTextLabel(nthColumn(1), "");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
_infoGroupsLabel = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Regions");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
label = new CTextLabel(nthColumn(1), "");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
_infoRegionsLabel = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Samples");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
label = new CTextLabel(nthColumn(1), "");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
_infoSamplesLabel = label;
panel->addView(label);
row.top += interRow;
row.bottom += interRow;
label = new CTextLabel(nthColumn(0), "Voices");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
panel->addView(label);
label = new CTextLabel(nthColumn(1), "");
label->setFontColor(CColor(0x00, 0x00, 0x00));
label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
label->setHoriAlign(kLeftText);
_infoVoicesLabel = label;
panel->addView(label);
_subPanels[kPanelInfo] = panel;
}
// all panels
for (unsigned currentPanel = 0; currentPanel < kNumPanels; ++currentPanel) {
panel = _subPanels[currentPanel];
CTextLabel* descLabel = new CTextLabel(
bottomRow, "Paul Ferrand and the SFZ Tools work group");
descLabel->setFontColor(CColor(0x00, 0x00, 0x00));
descLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00));
panel->addView(descLabel);
for (unsigned i = 0; i < kNumPanels; ++i) {
CRect btnRect = topRow;
btnRect.left = topRow.right - (kNumPanels - i) * 50;
btnRect.right = btnRect.left + 50;
const char *text;
switch (i) {
case kPanelGeneral: text = "File"; break;
case kPanelSettings: text = "Setup"; break;
case kPanelTuning: text = "Tuning"; break;
case kPanelInfo: text = "Info"; break;
default: text = "?"; break;
}
CTextButton* changePanelButton = new CTextButton(btnRect, this, kTagFirstChangePanel + i, text);
panel->addView(changePanelButton);
changePanelButton->setRoundRadius(0.0);
}
panel->setVisible(currentPanel == _activePanel);
}
}
void SfizzVstEditor::updateStateDisplay()
@ -686,196 +226,38 @@ void SfizzVstEditor::updateStateDisplay()
const SfizzPlayState& playState = controller->getSfizzPlayState();
///
updateSfzFileLabel(state.sfzFile);
if (_volumeSlider)
_volumeSlider->setValue(state.volume);
updateVolumeLabel(state.volume);
if (_numVoicesSlider)
_numVoicesSlider->setValue(state.numVoices);
updateNumVoicesLabel(state.numVoices);
if (_oversamplingSlider)
_oversamplingSlider->setValue(state.oversamplingLog2);
updateOversamplingLabel(state.oversamplingLog2);
if (_preloadSizeSlider)
_preloadSizeSlider->setValue(state.preloadSize);
updatePreloadSizeLabel(state.preloadSize);
updateScalaFileLabel(state.scalaFile);
if (_scalaRootKeySlider)
_scalaRootKeySlider->setValue(state.scalaRootKey);
updateScalaRootKeyLabel(state.scalaRootKey);
if (_tuningFrequencySlider)
_tuningFrequencySlider->setValue(state.tuningFrequency);
updateTuningFrequencyLabel(state.tuningFrequency);
if (_stretchedTuningSlider)
_stretchedTuningSlider->setValue(state.stretchedTuning);
updateStretchedTuningLabel(state.stretchedTuning);
uiReceiveValue(EditId::SfzFile, state.sfzFile);
uiReceiveValue(EditId::Volume, state.volume);
uiReceiveValue(EditId::Polyphony, state.numVoices);
uiReceiveValue(EditId::Oversampling, 1u << state.oversamplingLog2);
uiReceiveValue(EditId::PreloadSize, state.preloadSize);
uiReceiveValue(EditId::ScalaFile, state.scalaFile);
uiReceiveValue(EditId::ScalaRootKey, state.scalaRootKey);
uiReceiveValue(EditId::TuningFrequency, state.tuningFrequency);
uiReceiveValue(EditId::StretchTuning, state.stretchedTuning);
///
struct InfoLabel { const uint32* src; CTextLabel* dst; };
for (const auto& item : {
InfoLabel{&playState.curves, _infoCurvesLabel},
InfoLabel{&playState.masters, _infoMastersLabel},
InfoLabel{&playState.groups, _infoGroupsLabel},
InfoLabel{&playState.regions, _infoRegionsLabel},
InfoLabel{&playState.preloadedSamples, _infoSamplesLabel},
InfoLabel{&playState.activeVoices, _infoVoicesLabel} })
{
if (item.dst) {
char text[64];
sprintf(text, "%u", *item.src);
text[sizeof(text) - 1] = '\0';
item.dst->setText(text);
}
}
uiReceiveValue(EditId::UINumCurves, playState.curves);
uiReceiveValue(EditId::UINumMasters, playState.masters);
uiReceiveValue(EditId::UINumGroups, playState.groups);
uiReceiveValue(EditId::UINumRegions, playState.regions);
uiReceiveValue(EditId::UINumPreloadedSamples, playState.preloadedSamples);
uiReceiveValue(EditId::UINumActiveVoices, playState.activeVoices);
///
setActivePanel(uiState.activePanel);
uiReceiveValue(EditId::UIActivePanel, uiState.activePanel);
}
void SfizzVstEditor::updateSfzFileLabel(const std::string& filePath)
Vst::ParamID SfizzVstEditor::parameterOfEditId(EditId id)
{
updateLabelWithFileName(_sfzFileLabel, filePath);
}
void SfizzVstEditor::updateScalaFileLabel(const std::string& filePath)
{
updateLabelWithFileName(_scalaFileLabel, filePath);
}
void SfizzVstEditor::updateLabelWithFileName(CTextLabel* label, const std::string& filePath)
{
if (!label)
return;
std::string fileName;
if (filePath.empty())
fileName = "<No file>";
else {
#if defined (_WIN32)
size_t pos = filePath.find_last_of("/\\");
#else
size_t pos = filePath.rfind('/');
#endif
fileName = (pos != filePath.npos) ?
filePath.substr(pos + 1) : filePath;
}
label->setText(fileName.c_str());
}
void SfizzVstEditor::updateVolumeLabel(float volume)
{
CTextLabel* label = _volumeLabel;
if (!label)
return;
char text[64];
sprintf(text, "%.1f dB", volume);
text[sizeof(text) - 1] = '\0';
label->setText(text);
}
void SfizzVstEditor::updateNumVoicesLabel(int numVoices)
{
CTextLabel* label = _numVoicesLabel;
if (!label)
return;
char text[64];
sprintf(text, "%d", numVoices);
text[sizeof(text) - 1] = '\0';
label->setText(text);
}
void SfizzVstEditor::updateOversamplingLabel(int oversamplingLog2)
{
CTextLabel* label = _oversamplingLabel;
if (!label)
return;
char text[64];
sprintf(text, "%dx", 1 << oversamplingLog2);
text[sizeof(text) - 1] = '\0';
label->setText(text);
}
void SfizzVstEditor::updatePreloadSizeLabel(int preloadSize)
{
CTextLabel* label = _preloadSizeLabel;
if (!label)
return;
char text[64];
sprintf(text, "%.1f kB", preloadSize * (1.0 / 1024));
text[sizeof(text) - 1] = '\0';
label->setText(text);
}
void SfizzVstEditor::updateScalaRootKeyLabel(int rootKey)
{
CTextLabel* label = _scalaRootKeyLabel;
if (!label)
return;
static const char *octNoteNames[12] = {
"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B",
};
auto noteName = [](int key) -> std::string
{
int octNum;
int octNoteNum;
if (key >= 0) {
octNum = key / 12 - 1;
octNoteNum = key % 12;
}
else {
octNum = -2 - (key + 1) / -12;
octNoteNum = (key % 12 + 12) % 12;
}
return std::string(octNoteNames[octNoteNum]) + std::to_string(octNum);
};
label->setText(noteName(rootKey));
}
void SfizzVstEditor::updateTuningFrequencyLabel(float tuningFrequency)
{
CTextLabel* label = _tuningFrequencyLabel;
if (!label)
return;
char text[64];
sprintf(text, "%.1f", tuningFrequency);
text[sizeof(text) - 1] = '\0';
label->setText(text);
}
void SfizzVstEditor::updateStretchedTuningLabel(float stretchedTuning)
{
CTextLabel* label = _stretchedTuningLabel;
if (!label)
return;
char text[64];
sprintf(text, "%.3f", stretchedTuning);
text[sizeof(text) - 1] = '\0';
label->setText(text);
}
void SfizzVstEditor::setActivePanel(unsigned panelId)
{
panelId = std::max(0, std::min(kNumPanels - 1, static_cast<int>(panelId)));
getController()->getSfizzUiState().activePanel = panelId;
if (_activePanel != panelId) {
if (frame)
_subPanels[_activePanel]->setVisible(false);
_activePanel = panelId;
if (frame)
_subPanels[panelId]->setVisible(true);
switch (id) {
case EditId::Volume: return kPidVolume;
case EditId::Polyphony: return kPidNumVoices;
case EditId::Oversampling: return kPidOversampling;
case EditId::PreloadSize: return kPidPreloadSize;
case EditId::ScalaRootKey: return kPidScalaRootKey;
case EditId::TuningFrequency: return kPidTuningFrequency;
case EditId::StretchTuning: return kPidStretchedTuning;
default: return -1;
}
}

View file

@ -6,7 +6,9 @@
#pragma once
#include "SfizzVstController.h"
#include "editor/EditorController.h"
#include "public.sdk/source/vst/vstguieditor.h"
class Editor;
#if !defined(__APPLE__) && !defined(_WIN32)
namespace VSTGUI { class RunLoop; }
#endif
@ -14,7 +16,7 @@ namespace VSTGUI { class RunLoop; }
using namespace Steinberg;
using namespace VSTGUI;
class SfizzVstEditor : public Vst::VSTGUIEditor, public IControlListener, public SfizzVstController::StateListener {
class SfizzVstEditor : public Vst::VSTGUIEditor, public SfizzVstController::StateListener, public EditorController {
public:
explicit SfizzVstEditor(void *controller);
~SfizzVstEditor();
@ -27,98 +29,28 @@ public:
return static_cast<SfizzVstController*>(Vst::VSTGUIEditor::getController());
}
// IControlListener
void valueChanged(CControl* ctl) override;
void enterOrLeaveEdit(CControl* ctl, bool enter);
void controlBeginEdit(CControl* ctl) override;
void controlEndEdit(CControl* ctl) override;
// VSTGUIEditor
CMessageResult notify(CBaseObject* sender, const char* message) override;
// SfizzVstController::StateListener
void onStateChanged() override;
private:
void chooseSfzFile();
void loadSfzFile(const std::string& filePath);
protected:
// EditorController
void uiSendValue(EditId id, const EditValue& v) override;
void uiBeginSend(EditId id) override;
void uiEndSend(EditId id) override;
void uiSendMIDI(const uint8_t* msg, uint32_t len) override;
void chooseScalaFile();
private:
void loadSfzFile(const std::string& filePath);
void loadScalaFile(const std::string& filePath);
void createFrameContents();
void updateStateDisplay();
void updateSfzFileLabel(const std::string& filePath);
void updateScalaFileLabel(const std::string& filePath);
static void updateLabelWithFileName(CTextLabel* label, const std::string& filePath);
void updateVolumeLabel(float volume);
void updateNumVoicesLabel(int numVoices);
void updateOversamplingLabel(int oversamplingLog2);
void updatePreloadSizeLabel(int preloadSize);
void updateScalaRootKeyLabel(int rootKey);
void updateTuningFrequencyLabel(float tuningFrequency);
void updateStretchedTuningLabel(float stretchedTuning);
void setActivePanel(unsigned panelId);
template <class Control>
void adjustMinMaxToRangeParam(Control* c, Vst::ParamID id)
{
auto* p = static_cast<Vst::RangeParameter*>(getController()->getParameterObject(id));
c->setMin(p->getMin());
c->setMax(p->getMax());
c->setDefaultValue(p->toPlain(p->getInfo().defaultNormalizedValue));
}
Vst::ParamID parameterOfEditId(EditId id);
enum {
kPanelGeneral,
// kPanelControls,
kPanelSettings,
kPanelTuning,
kPanelInfo,
kNumPanels,
};
unsigned _activePanel = 0;
CViewContainer* _subPanels[kNumPanels] = {};
enum {
kTagLoadSfzFile,
kTagSetVolume,
kTagSetNumVoices,
kTagSetOversampling,
kTagSetPreloadSize,
kTagLoadScalaFile,
kTagSetScalaRootKey,
kTagSetTuningFrequency,
kTagSetStretchedTuning,
kTagFirstChangePanel,
kTagLastChangePanel = kTagFirstChangePanel + kNumPanels - 1,
};
CBitmap _logo;
CTextLabel* _sfzFileLabel = nullptr;
CTextLabel* _scalaFileLabel = nullptr;
CSliderBase *_volumeSlider = nullptr;
CTextLabel* _volumeLabel = nullptr;
CSliderBase *_numVoicesSlider = nullptr;
CTextLabel* _numVoicesLabel = nullptr;
CSliderBase *_oversamplingSlider = nullptr;
CTextLabel* _oversamplingLabel = nullptr;
CSliderBase *_preloadSizeSlider = nullptr;
CTextLabel* _preloadSizeLabel = nullptr;
CSliderBase *_scalaRootKeySlider = nullptr;
CTextLabel* _scalaRootKeyLabel = nullptr;
CSliderBase *_tuningFrequencySlider = nullptr;
CTextLabel* _tuningFrequencyLabel = nullptr;
CSliderBase *_stretchedTuningSlider = nullptr;
CTextLabel* _stretchedTuningLabel = nullptr;
CTextLabel* _infoCurvesLabel = nullptr;
CTextLabel* _infoMastersLabel = nullptr;
CTextLabel* _infoGroupsLabel = nullptr;
CTextLabel* _infoRegionsLabel = nullptr;
CTextLabel* _infoSamplesLabel = nullptr;
CTextLabel* _infoVoicesLabel = nullptr;
std::unique_ptr<Editor> editor_;
#if !defined(__APPLE__) && !defined(_WIN32)
SharedPointer<RunLoop> _runLoop;

View file

@ -289,15 +289,15 @@ void SfizzVstProcessor::processParameterChanges(Vst::IParameterChanges& pc)
break;
case kPidScalaRootKey:
if (pointCount > 0 && vq->getPoint(pointCount - 1, sampleOffset, value) == kResultTrue)
_state.scalaRootKey = static_cast<int32>(kParamScalaRootKey.denormalize(value));
_state.scalaRootKey = static_cast<int32>(kParamScalaRootKeyRange.denormalize(value));
break;
case kPidTuningFrequency:
if (pointCount > 0 && vq->getPoint(pointCount - 1, sampleOffset, value) == kResultTrue)
_state.tuningFrequency = kParamTuningFrequency.denormalize(value);
_state.tuningFrequency = kParamTuningFrequencyRange.denormalize(value);
break;
case kPidStretchedTuning:
if (pointCount > 0 && vq->getPoint(pointCount - 1, sampleOffset, value) == kResultTrue)
_state.stretchedTuning = kParamStretchedTuning.denormalize(value);
_state.stretchedTuning = kParamStretchedTuningRange.denormalize(value);
break;
}
}

View file

@ -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);

View file

@ -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()