Initial VST plugin
This commit is contained in:
parent
53a4cf0ead
commit
2dc41f4503
19 changed files with 1518 additions and 0 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -32,3 +32,6 @@ node_modules/
|
|||
*.lock
|
||||
*.sublime-*
|
||||
*.code-*
|
||||
|
||||
/vst/download
|
||||
/vst/external/VST_SDK
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ endif()
|
|||
option (ENABLE_LTO "Enable Link Time Optimization [default: ON]" ON)
|
||||
option (SFIZZ_JACK "Enable JACK stand-alone build [default: ON]" ON)
|
||||
option (SFIZZ_LV2 "Enable LV2 plug-in build [default: ON]" ON)
|
||||
option (SFIZZ_VST "Enable VST plug-in build [default: OFF]" OFF)
|
||||
option (SFIZZ_BENCHMARKS "Enable benchmarks build [default: OFF]" OFF)
|
||||
option (SFIZZ_TESTS "Enable tests build [default: OFF]" OFF)
|
||||
option (SFIZZ_SHARED "Enable shared library build [default: ON]" ON)
|
||||
|
|
@ -51,6 +52,10 @@ if (SFIZZ_LV2)
|
|||
add_subdirectory (lv2)
|
||||
endif()
|
||||
|
||||
if (SFIZZ_VST)
|
||||
add_subdirectory (vst)
|
||||
endif()
|
||||
|
||||
if (SFIZZ_BENCHMARKS)
|
||||
add_subdirectory (benchmarks)
|
||||
endif()
|
||||
|
|
|
|||
4
cmake/VSTConfig.cmake
Normal file
4
cmake/VSTConfig.cmake
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
set (VSTPLUGIN_NAME "sfizz")
|
||||
set (VSTPLUGIN_VENDOR "Paul Ferrand")
|
||||
set (VSTPLUGIN_URL "http://sfztools.github.io/sfizz")
|
||||
set (VSTPLUGIN_EMAIL "paul@ferrand.cc")
|
||||
77
vst/CMakeLists.txt
Normal file
77
vst/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
set (VSTPLUGIN_PRJ_NAME "${PROJECT_NAME}_vst3")
|
||||
set (VSTPLUGIN_BUNDLE_NAME "${PROJECT_NAME}.vst3")
|
||||
|
||||
set (VST3SDK_BASEDIR "${CMAKE_CURRENT_SOURCE_DIR}/external/VST_SDK/VST3_SDK")
|
||||
set (VST3SDK_ARCHIVE "vst-sdk_3.6.14_build-24_2019-11-29.zip")
|
||||
|
||||
if (NOT EXISTS "${VST3SDK_BASEDIR}")
|
||||
message (STATUS "VST3 SDK is not found, downloading")
|
||||
|
||||
execute_process (
|
||||
COMMAND "${CMAKE_COMMAND}" -E make_directory "${CMAKE_CURRENT_SOURCE_DIR}/download")
|
||||
|
||||
if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/download/${VST3SDK_ARCHIVE}")
|
||||
file (DOWNLOAD
|
||||
"https://download.steinberg.net/sdk_downloads/${VST3SDK_ARCHIVE}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/download/${VST3SDK_ARCHIVE}"
|
||||
SHOW_PROGRESS)
|
||||
endif()
|
||||
|
||||
execute_process (
|
||||
COMMAND "${CMAKE_COMMAND}" -E make_directory "${CMAKE_CURRENT_SOURCE_DIR}/external"
|
||||
COMMAND "${CMAKE_COMMAND}" -E tar xvf "../download/${VST3SDK_ARCHIVE}"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/external")
|
||||
endif()
|
||||
|
||||
# stop trying to include this atrocity.. build it ourselves
|
||||
#add_subdirectory("${VST3SDK_BASEDIR}" EXCLUDE_FROM_ALL)
|
||||
|
||||
# VST plugin specific settings
|
||||
include (VSTConfig)
|
||||
|
||||
configure_file (VstPluginDefs.h.in "${CMAKE_CURRENT_BINARY_DIR}/VstPluginDefs.h")
|
||||
|
||||
# Build VST3 SDK
|
||||
include("cmake/Vst3.cmake")
|
||||
|
||||
# Build the plugin
|
||||
add_library(${VSTPLUGIN_PRJ_NAME} MODULE
|
||||
SfizzVstProcessor.cpp
|
||||
SfizzVstController.cpp
|
||||
SfizzVstEditor.cpp
|
||||
SfizzVstState.cpp
|
||||
VstPluginFactory.cpp)
|
||||
target_link_libraries(${VSTPLUGIN_PRJ_NAME}
|
||||
PRIVATE ${PROJECT_NAME}::${PROJECT_NAME})
|
||||
target_include_directories(${VSTPLUGIN_PRJ_NAME}
|
||||
PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
set_target_properties(${VSTPLUGIN_PRJ_NAME} PROPERTIES
|
||||
OUTPUT_NAME "${PROJECT_NAME}"
|
||||
PREFIX "")
|
||||
|
||||
plugin_add_vst3sdk(${VSTPLUGIN_PRJ_NAME})
|
||||
plugin_add_vstgui(${VSTPLUGIN_PRJ_NAME})
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
target_link_libraries(${VSTPLUGIN_PRJ_NAME} PRIVATE
|
||||
"-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/vst3.version")
|
||||
endif()
|
||||
|
||||
# Create the bundle (see "VST 3 Locations / Format")
|
||||
if(WIN32)
|
||||
set_target_properties(${VSTPLUGIN_PRJ_NAME} PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/${VST3_PACKAGE_ARCHITECTURE}-win")
|
||||
# TODO: make desktop.ini, Plugin.ico
|
||||
elseif(APPLE)
|
||||
set_target_properties(${VSTPLUGIN_PRJ_NAME} PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/MacOS")
|
||||
# TODO: make Info.plist, PkgInfo
|
||||
else()
|
||||
set_target_properties(${VSTPLUGIN_PRJ_NAME} PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${VSTPLUGIN_BUNDLE_NAME}/Contents/${VST3_PACKAGE_ARCHITECTURE}-linux")
|
||||
endif()
|
||||
|
||||
# To help debugging the link only
|
||||
if (FALSE)
|
||||
target_link_options(${VSTPLUGIN_PRJ_NAME} PRIVATE "-Wl,-no-undefined")
|
||||
endif()
|
||||
167
vst/RTSemaphore.h
Normal file
167
vst/RTSemaphore.h
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
// Copyright Jean Pierre Cimalando 2018-2020.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#pragma once
|
||||
#if defined(__APPLE__)
|
||||
#include <mach/mach.h>
|
||||
#elif defined(_WIN32)
|
||||
#include <limits.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <semaphore.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include <stdexcept>
|
||||
|
||||
class RTSemaphore {
|
||||
public:
|
||||
explicit RTSemaphore(unsigned value = 0);
|
||||
~RTSemaphore();
|
||||
|
||||
RTSemaphore(const RTSemaphore &) = delete;
|
||||
RTSemaphore &operator=(const RTSemaphore &) = delete;
|
||||
|
||||
void post();
|
||||
void wait();
|
||||
bool try_wait();
|
||||
|
||||
private:
|
||||
#if defined(__APPLE__)
|
||||
semaphore_t sem_;
|
||||
#elif defined(_WIN32)
|
||||
HANDLE sem_;
|
||||
#else
|
||||
sem_t sem_;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if defined(__APPLE__)
|
||||
inline RTSemaphore::RTSemaphore(unsigned value)
|
||||
{
|
||||
if (semaphore_create(mach_task_self(), &sem_, SYNC_POLICY_FIFO, value) != 0)
|
||||
throw std::runtime_error("RTSemaphore::RTSemaphore");
|
||||
}
|
||||
|
||||
inline RTSemaphore::~RTSemaphore()
|
||||
{
|
||||
semaphore_destroy(mach_task_self(), sem_);
|
||||
}
|
||||
|
||||
inline void RTSemaphore::post()
|
||||
{
|
||||
if (semaphore_signal(sem_) != KERN_SUCCESS)
|
||||
throw std::runtime_error("RTSemaphore::post");
|
||||
}
|
||||
|
||||
inline void RTSemaphore::wait()
|
||||
{
|
||||
do {
|
||||
switch (semaphore_wait(sem_)) {
|
||||
case KERN_SUCCESS:
|
||||
return;
|
||||
case KERN_ABORTED:
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("RTSemaphore::wait");
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
|
||||
inline bool RTSemaphore::try_wait()
|
||||
{
|
||||
do {
|
||||
const mach_timespec_t timeout = {0, 0};
|
||||
switch (semaphore_timedwait(sem_, timeout)) {
|
||||
case KERN_SUCCESS:
|
||||
return true;
|
||||
case KERN_OPERATION_TIMED_OUT:
|
||||
return false;
|
||||
case KERN_ABORTED:
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("RTSemaphore::try_wait");
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
#elif defined(_WIN32)
|
||||
inline RTSemaphore::RTSemaphore(unsigned value)
|
||||
{
|
||||
sem_ = CreateRTSemaphore(nullptr, value, LONG_MAX, nullptr);
|
||||
if (!sem_)
|
||||
throw std::runtime_error("RTSemaphore::RTSemaphore");
|
||||
}
|
||||
|
||||
inline RTSemaphore::~RTSemaphore()
|
||||
{
|
||||
CloseHandle(sem_);
|
||||
}
|
||||
|
||||
inline void RTSemaphore::post()
|
||||
{
|
||||
if (!ReleaseRTSemaphore(sem_, 1, nullptr))
|
||||
throw std::runtime_error("RTSemaphore::post");
|
||||
}
|
||||
|
||||
inline void RTSemaphore::wait()
|
||||
{
|
||||
if (WaitForSingleObject(sem_, INFINITE) != WAIT_OBJECT_0)
|
||||
throw std::runtime_error("RTSemaphore::wait");
|
||||
}
|
||||
|
||||
inline bool RTSemaphore::try_wait()
|
||||
{
|
||||
switch (WaitForSingleObject(sem_, 0)) {
|
||||
case WAIT_OBJECT_0:
|
||||
return true;
|
||||
case WAIT_TIMEOUT:
|
||||
return false;
|
||||
default:
|
||||
throw std::runtime_error("RTSemaphore::try_wait");
|
||||
}
|
||||
}
|
||||
#else
|
||||
inline RTSemaphore::RTSemaphore(unsigned value)
|
||||
{
|
||||
if (sem_init(&sem_, 0, value) != 0)
|
||||
throw std::runtime_error("RTSemaphore::RTSemaphore");
|
||||
}
|
||||
|
||||
inline RTSemaphore::~RTSemaphore()
|
||||
{
|
||||
sem_destroy(&sem_);
|
||||
}
|
||||
|
||||
inline void RTSemaphore::post()
|
||||
{
|
||||
while (sem_post(&sem_) != 0) {
|
||||
if (errno != EINTR)
|
||||
throw std::runtime_error("RTSemaphore::post");
|
||||
}
|
||||
}
|
||||
|
||||
inline void RTSemaphore::wait()
|
||||
{
|
||||
while (sem_wait(&sem_) != 0) {
|
||||
if (errno != EINTR)
|
||||
throw std::runtime_error("RTSemaphore::wait");
|
||||
}
|
||||
}
|
||||
|
||||
inline bool RTSemaphore::try_wait()
|
||||
{
|
||||
do {
|
||||
if (sem_trywait(&sem_) == 0)
|
||||
return true;
|
||||
switch (errno) {
|
||||
case EINTR:
|
||||
break;
|
||||
case EAGAIN:
|
||||
return false;
|
||||
default:
|
||||
throw std::runtime_error("RTSemaphore::try_wait");
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
#endif
|
||||
121
vst/SfizzVstController.cpp
Normal file
121
vst/SfizzVstController.cpp
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
// 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 "SfizzVstController.h"
|
||||
#include "SfizzVstEditor.h"
|
||||
#include "base/source/fstreamer.h"
|
||||
#include "pluginterfaces/vst/ivstmidicontrollers.h"
|
||||
|
||||
tresult PLUGIN_API SfizzVstControllerNoUi::initialize(FUnknown* context)
|
||||
{
|
||||
tresult result = EditController::initialize(context);
|
||||
if (result != kResultTrue)
|
||||
return result;
|
||||
|
||||
Vst::ParamID pid = 0;
|
||||
|
||||
// MIDI controllers
|
||||
for (unsigned i = 0; i < numControllerParams; ++i) {
|
||||
Steinberg::String title;
|
||||
Steinberg::String shortTitle;
|
||||
title.printf("Controller %u", i);
|
||||
shortTitle.printf("CC%u", i);
|
||||
|
||||
parameters.addParameter(
|
||||
title, nullptr, 0, 0, Vst::ParameterInfo::kCanAutomate,
|
||||
pid++, Vst::kRootUnitId, shortTitle);
|
||||
}
|
||||
|
||||
// MIDI extra controllers
|
||||
parameters.addParameter(Steinberg::String("Aftertouch"), nullptr, 0, 0.5, 0, pid++, Vst::kRootUnitId);
|
||||
parameters.addParameter(Steinberg::String("Pitch Bend"), nullptr, 0, 0.5, 0, pid++, Vst::kRootUnitId);
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
tresult PLUGIN_API SfizzVstControllerNoUi::terminate()
|
||||
{
|
||||
return EditController::terminate();
|
||||
}
|
||||
|
||||
tresult PLUGIN_API SfizzVstControllerNoUi::getMidiControllerAssignment(int32 busIndex, int16 channel, Vst::CtrlNumber midiControllerNumber, Vst::ParamID& id)
|
||||
{
|
||||
switch (midiControllerNumber) {
|
||||
case Vst::kAfterTouch:
|
||||
id = kPidMidiAftertouch;
|
||||
return kResultTrue;
|
||||
|
||||
case Vst::kPitchBend:
|
||||
id = kPidMidiPitchBend;
|
||||
return kResultTrue;
|
||||
|
||||
default:
|
||||
if (midiControllerNumber < 0 || midiControllerNumber >= numControllerParams)
|
||||
return kResultFalse;
|
||||
|
||||
id = kPidMidiCC0 + midiControllerNumber;
|
||||
return kResultTrue;
|
||||
}
|
||||
}
|
||||
|
||||
// --- Controller with UI --- //
|
||||
|
||||
IPlugView* PLUGIN_API SfizzVstController::createView(FIDString _name)
|
||||
{
|
||||
ConstString name(_name);
|
||||
|
||||
if (name != Vst::ViewType::kEditor)
|
||||
return nullptr;
|
||||
|
||||
return new SfizzVstEditor(this);
|
||||
}
|
||||
|
||||
tresult PLUGIN_API SfizzVstController::setParamNormalized(Vst::ParamID tag, Vst::ParamValue value)
|
||||
{
|
||||
tresult r = SfizzVstControllerNoUi::setParamNormalized(tag, value);
|
||||
if (r != kResultTrue)
|
||||
return r;
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
tresult PLUGIN_API SfizzVstController::setComponentState(IBStream* state)
|
||||
{
|
||||
SfizzVstState s;
|
||||
|
||||
tresult r = s.load(state);
|
||||
if (r != kResultTrue)
|
||||
return r;
|
||||
|
||||
for (StateListener* listener : _stateListeners)
|
||||
listener->onStateChanged();
|
||||
|
||||
_state = s;
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
void SfizzVstController::addStateListener(StateListener* listener)
|
||||
{
|
||||
_stateListeners.push_back(listener);
|
||||
}
|
||||
|
||||
void SfizzVstController::removeStateListener(StateListener* listener)
|
||||
{
|
||||
auto it = std::find(_stateListeners.begin(), _stateListeners.end(), listener);
|
||||
if (it != _stateListeners.end())
|
||||
_stateListeners.erase(it);
|
||||
}
|
||||
|
||||
FUnknown* SfizzVstController::createInstance(void*)
|
||||
{
|
||||
return static_cast<Vst::IEditController*>(new SfizzVstController);
|
||||
}
|
||||
|
||||
/*
|
||||
Note(jpc) Generated at random with uuidgen.
|
||||
Can't find docs on it... maybe it's to register somewhere?
|
||||
*/
|
||||
FUID SfizzVstController::cid(0x7129736c, 0xbc784134, 0xbb899d56, 0x2ebafe4f);
|
||||
69
vst/SfizzVstController.h
Normal file
69
vst/SfizzVstController.h
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
// 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 "SfizzVstState.h"
|
||||
#include "public.sdk/source/vst/vsteditcontroller.h"
|
||||
#include "public.sdk/source/vst/vstparameters.h"
|
||||
#include "vstgui/plugin-bindings/vst3editor.h"
|
||||
class SfizzVstState;
|
||||
|
||||
using namespace Steinberg;
|
||||
using namespace VSTGUI;
|
||||
|
||||
class SfizzVstControllerNoUi : public Vst::EditController,
|
||||
public Vst::IMidiMapping {
|
||||
public:
|
||||
virtual ~SfizzVstControllerNoUi() {}
|
||||
|
||||
tresult PLUGIN_API initialize(FUnknown* context) override;
|
||||
tresult PLUGIN_API terminate() override;
|
||||
|
||||
tresult PLUGIN_API getMidiControllerAssignment(int32 busIndex, int16 channel, Vst::CtrlNumber midiControllerNumber, Vst::ParamID& id) override;
|
||||
|
||||
enum { numControllerParams = 128 };
|
||||
|
||||
// interfaces
|
||||
OBJ_METHODS(SfizzVstControllerNoUi, Vst::EditController)
|
||||
DEFINE_INTERFACES
|
||||
DEF_INTERFACE(Vst::IMidiMapping)
|
||||
END_DEFINE_INTERFACES(Vst::EditController)
|
||||
REFCOUNT_METHODS(Vst::EditController)
|
||||
|
||||
enum {
|
||||
kPidMidiCC0,
|
||||
kPidMidiCCLast = kPidMidiCC0 + numControllerParams - 1,
|
||||
kPidMidiAftertouch,
|
||||
kPidMidiPitchBend,
|
||||
/* Reserved */
|
||||
};
|
||||
};
|
||||
|
||||
class SfizzVstController : public SfizzVstControllerNoUi, public VSTGUI::VST3EditorDelegate {
|
||||
public:
|
||||
IPlugView* PLUGIN_API createView(FIDString name) override;
|
||||
|
||||
tresult PLUGIN_API setParamNormalized(Vst::ParamID tag, Vst::ParamValue value) override;
|
||||
tresult PLUGIN_API setComponentState(IBStream* state) override;
|
||||
|
||||
struct StateListener {
|
||||
virtual void onStateChanged() = 0;
|
||||
};
|
||||
|
||||
const SfizzVstState& getSfizzState() const { return _state; }
|
||||
|
||||
void addStateListener(StateListener* listener);
|
||||
void removeStateListener(StateListener* listener);
|
||||
|
||||
///
|
||||
static FUnknown* createInstance(void*);
|
||||
|
||||
static FUID cid;
|
||||
|
||||
private:
|
||||
SfizzVstState _state;
|
||||
std::vector<StateListener*> _stateListeners;
|
||||
};
|
||||
180
vst/SfizzVstEditor.cpp
Normal file
180
vst/SfizzVstEditor.cpp
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
// 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 "SfizzVstEditor.h"
|
||||
#include "SfizzVstState.h"
|
||||
#if !defined(__APPLE__) && !defined(_WIN32)
|
||||
#include "x11runloop.h"
|
||||
#endif
|
||||
|
||||
using namespace VSTGUI;
|
||||
|
||||
static constexpr int kEditorWidth = 800;
|
||||
static constexpr int kEditorHeight = 40;
|
||||
|
||||
SfizzVstEditor::SfizzVstEditor(void *controller)
|
||||
: VSTGUIEditor(controller)
|
||||
{
|
||||
static_cast<SfizzVstController*>(getController())->addStateListener(this);
|
||||
}
|
||||
|
||||
SfizzVstEditor::~SfizzVstEditor()
|
||||
{
|
||||
static_cast<SfizzVstController*>(getController())->removeStateListener(this);
|
||||
}
|
||||
|
||||
bool PLUGIN_API SfizzVstEditor::open(void* parent, const VSTGUI::PlatformType& platformType)
|
||||
{
|
||||
CRect wsize(0, 0, kEditorWidth, kEditorHeight);
|
||||
CFrame *frame = new CFrame(wsize, this);
|
||||
this->frame = frame;
|
||||
|
||||
IPlatformFrameConfig* config = nullptr;
|
||||
|
||||
#if !defined(__APPLE__) && !defined(_WIN32)
|
||||
X11::FrameConfig x11config;
|
||||
x11config.runLoop = VSTGUI::owned(new RunLoop(plugFrame));
|
||||
config = &x11config;
|
||||
#endif
|
||||
|
||||
createFrameContents();
|
||||
updateStateDisplay();
|
||||
|
||||
frame->open(parent, platformType, config);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PLUGIN_API SfizzVstEditor::close()
|
||||
{
|
||||
CFrame *frame = this->frame;
|
||||
if (frame) {
|
||||
frame->forget();
|
||||
this->frame = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
void SfizzVstEditor::valueChanged(CControl* ctl)
|
||||
{
|
||||
int32_t tag = ctl->getTag();
|
||||
float value = ctl->getValue();
|
||||
|
||||
switch (tag) {
|
||||
case kTagLoadSfzFile:
|
||||
if (value != 1)
|
||||
break;
|
||||
|
||||
chooseSfzFile();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SfizzVstEditor::onStateChanged()
|
||||
{
|
||||
updateStateDisplay();
|
||||
}
|
||||
|
||||
///
|
||||
void SfizzVstEditor::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)
|
||||
loadSfzFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
void SfizzVstEditor::loadSfzFile(const std::string& filePath)
|
||||
{
|
||||
_fileLabel->setText(filePath.c_str());
|
||||
|
||||
Vst::EditController* ctl = getController();
|
||||
|
||||
Vst::IMessage *msg = ctl->allocateMessage();
|
||||
if (msg) {
|
||||
msg->setMessageID("LoadSfz");
|
||||
Vst::IAttributeList* attr = msg->getAttributes();
|
||||
attr->setString("File", Steinberg::String(filePath.c_str()).text());
|
||||
ctl->sendMessage(msg);
|
||||
msg->release();
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
class SimpleButton : public CControl {
|
||||
public:
|
||||
explicit SimpleButton(const CRect& size, IControlListener* listener = nullptr, int32_t tag = -1, UTF8StringPtr title = nullptr)
|
||||
: CControl(size, listener, tag), _title(title ? title : "") {
|
||||
}
|
||||
|
||||
void draw(CDrawContext *dc) override
|
||||
{
|
||||
CRect bounds = getViewSize();
|
||||
dc->setFrameColor(CColor(0xff, 0xff, 0xff));
|
||||
dc->drawRect(bounds, kDrawStroked);
|
||||
dc->drawString(_title.c_str(), bounds);
|
||||
}
|
||||
|
||||
CMouseEventResult onMouseDown(CPoint& where, const CButtonState& buttons) override
|
||||
{
|
||||
if (!buttons.isLeftButton())
|
||||
return kMouseEventNotHandled;
|
||||
|
||||
value = getMin();
|
||||
if (isDirty()) {
|
||||
valueChanged();
|
||||
invalid();
|
||||
}
|
||||
value = getMax();
|
||||
if (isDirty())
|
||||
{
|
||||
valueChanged();
|
||||
invalid();
|
||||
}
|
||||
|
||||
return kMouseEventHandled;
|
||||
}
|
||||
|
||||
CLASS_METHODS(SimpleButton, CControl)
|
||||
|
||||
private:
|
||||
std::string _title;
|
||||
};
|
||||
|
||||
///
|
||||
void SfizzVstEditor::createFrameContents()
|
||||
{
|
||||
CFrame* frame = this->frame;
|
||||
CRect bounds = frame->getViewSize();
|
||||
|
||||
CTextLabel *label;
|
||||
CRect rect;
|
||||
CRect rect2;
|
||||
|
||||
rect = CRect(10.0, 10.0, 120.0, 30.0);
|
||||
frame->addView(new SimpleButton(rect, this, kTagLoadSfzFile, "Load SFZ file"));
|
||||
|
||||
rect2 = CRect(150.0, 10.0, bounds.right - 10.0, 30.0);
|
||||
frame->addView((label = new CTextLabel(rect2, "no file")));
|
||||
label->setHoriAlign(kLeftText);
|
||||
_fileLabel = label;
|
||||
}
|
||||
|
||||
void SfizzVstEditor::updateStateDisplay()
|
||||
{
|
||||
if (!frame)
|
||||
return;
|
||||
|
||||
const SfizzVstState& state = static_cast<SfizzVstController*>(getController())->getSfizzState();
|
||||
|
||||
_fileLabel->setText(state.sfzFile.c_str());
|
||||
}
|
||||
40
vst/SfizzVstEditor.h
Normal file
40
vst/SfizzVstEditor.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// 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 "SfizzVstController.h"
|
||||
#include "public.sdk/source/vst/vstguieditor.h"
|
||||
|
||||
using namespace Steinberg;
|
||||
using namespace VSTGUI;
|
||||
|
||||
class SfizzVstEditor : public Vst::VSTGUIEditor, public IControlListener, public SfizzVstController::StateListener {
|
||||
public:
|
||||
explicit SfizzVstEditor(void *controller);
|
||||
~SfizzVstEditor();
|
||||
|
||||
bool PLUGIN_API open(void* parent, const VSTGUI::PlatformType& platformType = VSTGUI::kDefaultNative) override;
|
||||
void PLUGIN_API close() override;
|
||||
|
||||
// IControlListener
|
||||
void valueChanged(CControl* ctl) override;
|
||||
|
||||
// SfizzVstController::StateListener
|
||||
void onStateChanged() override;
|
||||
|
||||
private:
|
||||
void chooseSfzFile();
|
||||
void loadSfzFile(const std::string& filePath);
|
||||
|
||||
void createFrameContents();
|
||||
void updateStateDisplay();
|
||||
|
||||
enum {
|
||||
kTagLoadSfzFile,
|
||||
};
|
||||
|
||||
CTextLabel* _fileLabel = nullptr;
|
||||
};
|
||||
284
vst/SfizzVstProcessor.cpp
Normal file
284
vst/SfizzVstProcessor.cpp
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
// 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 "SfizzVstProcessor.h"
|
||||
#include "SfizzVstController.h"
|
||||
#include "SfizzVstState.h"
|
||||
#include "base/source/fstreamer.h"
|
||||
#include "pluginterfaces/vst/ivstevents.h"
|
||||
#include "pluginterfaces/vst/ivstparameterchanges.h"
|
||||
#include <cstring>
|
||||
|
||||
#pragma message("TODO: send tempo")
|
||||
|
||||
SfizzVstProcessor::SfizzVstProcessor()
|
||||
: _fifoToWorker(1024)
|
||||
{
|
||||
setControllerClass(SfizzVstController::cid);
|
||||
}
|
||||
|
||||
SfizzVstProcessor::~SfizzVstProcessor()
|
||||
{
|
||||
setActive(false); // to be sure
|
||||
}
|
||||
|
||||
tresult PLUGIN_API SfizzVstProcessor::initialize(FUnknown* context)
|
||||
{
|
||||
tresult result = AudioEffect::initialize(context);
|
||||
if (result != kResultTrue)
|
||||
return result;
|
||||
|
||||
addAudioOutput(STR16("Audio Output"), Vst::SpeakerArr::kStereo);
|
||||
addEventInput(STR16("Event Input"), 1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
tresult PLUGIN_API SfizzVstProcessor::setBusArrangements(Vst::SpeakerArrangement* inputs, int32 numIns, Vst::SpeakerArrangement* outputs, int32 numOuts)
|
||||
{
|
||||
bool isStereo = numIns == 0 && numOuts == 1 && outputs[0] == Vst::SpeakerArr::kStereo;
|
||||
|
||||
if (!isStereo)
|
||||
return kResultFalse;
|
||||
|
||||
return AudioEffect::setBusArrangements(inputs, numIns, outputs, numOuts);
|
||||
}
|
||||
|
||||
tresult PLUGIN_API SfizzVstProcessor::setState(IBStream* state)
|
||||
{
|
||||
SfizzVstState s;
|
||||
|
||||
tresult r = s.load(state);
|
||||
if (r != kResultTrue)
|
||||
return r;
|
||||
|
||||
loadSfzFile(s.sfzFile);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
tresult PLUGIN_API SfizzVstProcessor::getState(IBStream* state)
|
||||
{
|
||||
SfizzVstState s;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_processMutex);
|
||||
s.sfzFile = _sfzFile;
|
||||
}
|
||||
|
||||
return s.store(state);
|
||||
}
|
||||
|
||||
tresult PLUGIN_API SfizzVstProcessor::canProcessSampleSize(int32 symbolicSampleSize)
|
||||
{
|
||||
if (symbolicSampleSize != Vst::kSample32)
|
||||
return kResultFalse;
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
tresult PLUGIN_API SfizzVstProcessor::setActive(TBool state)
|
||||
{
|
||||
stopBackgroundWork();
|
||||
_synth.reset();
|
||||
|
||||
if (state) {
|
||||
fprintf(stderr, "[Sfizz] new synth\n");
|
||||
sfz::Sfizz* synth = new sfz::Sfizz;
|
||||
_synth.reset(synth);
|
||||
|
||||
synth->setSampleRate(processSetup.sampleRate);
|
||||
synth->setSamplesPerBlock(processSetup.maxSamplesPerBlock);
|
||||
|
||||
loadSfzFile(_sfzFile);
|
||||
|
||||
_workRunning = true;
|
||||
_worker = std::thread([this]() { doBackgroundWork(); });
|
||||
}
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
tresult PLUGIN_API SfizzVstProcessor::process(Vst::ProcessData& data)
|
||||
{
|
||||
sfz::Sfizz& synth = *_synth;
|
||||
|
||||
if (data.numOutputs < 1) // flush mode
|
||||
return kResultTrue;
|
||||
|
||||
uint32 numFrames = data.numSamples;
|
||||
constexpr uint32 numChannels = 2;
|
||||
float* outputs[numChannels];
|
||||
|
||||
assert(numChannels == data.outputs[0].numChannels);
|
||||
|
||||
for (unsigned c = 0; c < numChannels; ++c)
|
||||
outputs[c] = data.outputs[0].channelBuffers32[c];
|
||||
|
||||
std::unique_lock<std::mutex> lock(_processMutex, std::try_to_lock);
|
||||
if (!lock.owns_lock()) {
|
||||
for (unsigned c = 0; c < numChannels; ++c)
|
||||
std::memset(outputs[c], 0, numFrames * sizeof(float));
|
||||
data.outputs[0].silenceFlags = 3;
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
if (Vst::IParameterChanges* pc = data.inputParameterChanges) {
|
||||
uint32 paramCount = pc->getParameterCount();
|
||||
|
||||
for (uint32 paramIndex = 0; paramIndex < paramCount; ++paramIndex) {
|
||||
Vst::IParamValueQueue* vq = pc->getParameterData(paramIndex);
|
||||
|
||||
Vst::ParamID id = vq->getParameterId();
|
||||
|
||||
switch (id) {
|
||||
default:
|
||||
if (id >= SfizzVstController::kPidMidiCC0 && id <= SfizzVstController::kPidMidiCCLast) {
|
||||
int ccNumber = id - SfizzVstController::kPidMidiCC0;
|
||||
for (uint32 pointIndex = 0, pointCount = vq->getPointCount(); pointIndex < pointCount; ++pointIndex) {
|
||||
int32 sampleOffset;
|
||||
Vst::ParamValue value;
|
||||
if (vq->getPoint(pointIndex, sampleOffset, value) == kResultTrue)
|
||||
synth.cc(sampleOffset, ccNumber, (int)(0.5 + value * 127.0));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SfizzVstController::kPidMidiAftertouch:
|
||||
for (uint32 pointIndex = 0, pointCount = vq->getPointCount(); pointIndex < pointCount; ++pointIndex) {
|
||||
int32 sampleOffset;
|
||||
Vst::ParamValue value;
|
||||
if (vq->getPoint(pointIndex, sampleOffset, value) == kResultTrue)
|
||||
synth.aftertouch(sampleOffset, (int)(0.5 + value * 127.0));
|
||||
}
|
||||
break;
|
||||
|
||||
case SfizzVstController::kPidMidiPitchBend:
|
||||
for (uint32 pointIndex = 0, pointCount = vq->getPointCount(); pointIndex < pointCount; ++pointIndex) {
|
||||
int32 sampleOffset;
|
||||
Vst::ParamValue value;
|
||||
if (vq->getPoint(pointIndex, sampleOffset, value) == kResultTrue)
|
||||
synth.pitchWheel(sampleOffset, (int)(0.5 + value * 16383) - 8192);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Vst::IEventList* events = data.inputEvents) {
|
||||
uint32 numEvents = events->getEventCount();
|
||||
|
||||
for (uint32 i = 0; i < numEvents; i++) {
|
||||
Vst::Event e;
|
||||
if (events->getEvent(i, e) != kResultTrue)
|
||||
continue;
|
||||
|
||||
auto convertVelocityFromFloat = [](float x) -> int {
|
||||
return std::min(127, std::max(0, (int)(x * 127.0f)));
|
||||
};
|
||||
|
||||
switch (e.type) {
|
||||
case Vst::Event::kNoteOnEvent:
|
||||
synth.noteOn(e.sampleOffset, e.noteOn.pitch, convertVelocityFromFloat(e.noteOn.velocity));
|
||||
break;
|
||||
case Vst::Event::kNoteOffEvent:
|
||||
synth.noteOff(e.sampleOffset, e.noteOff.pitch, convertVelocityFromFloat(e.noteOff.velocity));
|
||||
break;
|
||||
// case Vst::Event::kPolyPressureEvent:
|
||||
// synth.aftertouch(e.sampleOffset, convertVelocityFromFloat(e.polyPressure.pressure));
|
||||
// break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
synth.renderBlock(outputs, numFrames, numChannels);
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
tresult PLUGIN_API SfizzVstProcessor::notify(Vst::IMessage* message)
|
||||
{
|
||||
tresult result = AudioEffect::notify(message);
|
||||
if (result != kResultFalse)
|
||||
return result;
|
||||
|
||||
if (!_fifoToWorker.push(message))
|
||||
return kOutOfMemory;
|
||||
|
||||
message->addRef();
|
||||
_semaToWorker.post();
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
FUnknown* SfizzVstProcessor::createInstance(void*)
|
||||
{
|
||||
return static_cast<Vst::IAudioProcessor*>(new SfizzVstProcessor);
|
||||
}
|
||||
|
||||
void SfizzVstProcessor::loadSfzFile(std::string file)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_processMutex);
|
||||
|
||||
if (_synth) {
|
||||
fprintf(stderr, "[Sfizz] load SFZ file: %s\n", file.c_str());
|
||||
_synth->loadSfzFile(file);
|
||||
}
|
||||
|
||||
_sfzFile = std::move(file);
|
||||
}
|
||||
|
||||
void SfizzVstProcessor::doBackgroundWork()
|
||||
{
|
||||
constexpr uint32 maxPathLen = 32768;
|
||||
|
||||
for (;;) {
|
||||
_semaToWorker.wait();
|
||||
|
||||
if (!_workRunning)
|
||||
break;
|
||||
|
||||
Vst::IMessage* msg;
|
||||
if (!_fifoToWorker.pop(msg)) {
|
||||
fprintf(stderr, "[Sfizz] message synchronization error in worker\n");
|
||||
std::abort();
|
||||
}
|
||||
|
||||
const char* id = msg->getMessageID();
|
||||
Vst::IAttributeList* attr = msg->getAttributes();
|
||||
|
||||
if (!std::strcmp(id, "LoadSfz")) {
|
||||
std::vector<Vst::TChar> path(maxPathLen + 1);
|
||||
if (attr->getString("File", path.data(), maxPathLen) == kResultTrue)
|
||||
loadSfzFile(Steinberg::String(path.data()).text8());
|
||||
}
|
||||
|
||||
msg->release();
|
||||
}
|
||||
}
|
||||
|
||||
void SfizzVstProcessor::stopBackgroundWork()
|
||||
{
|
||||
if (!_workRunning)
|
||||
return;
|
||||
|
||||
_workRunning = false;
|
||||
_semaToWorker.post();
|
||||
_worker.join();
|
||||
|
||||
while (_semaToWorker.try_wait()) {
|
||||
Vst::IMessage* msg;
|
||||
if (!_fifoToWorker.pop(msg)) {
|
||||
fprintf(stderr, "[Sfizz] message synchronization error in processor\n");
|
||||
std::abort();
|
||||
}
|
||||
msg->release();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Note(jpc) Generated at random with uuidgen.
|
||||
Can't find docs on it... maybe it's to register somewhere?
|
||||
*/
|
||||
FUID SfizzVstProcessor::cid(0xe8fab718, 0x15ed46e3, 0x8b598310, 0x1e12993f);
|
||||
57
vst/SfizzVstProcessor.h
Normal file
57
vst/SfizzVstProcessor.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
// 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 "public.sdk/source/vst/vstaudioeffect.h"
|
||||
#include "public.sdk/source/vst/utility/ringbuffer.h"
|
||||
#include "RTSemaphore.h"
|
||||
#include <sfizz.hpp>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
|
||||
using namespace Steinberg;
|
||||
|
||||
class SfizzVstProcessor : public Vst::AudioEffect {
|
||||
public:
|
||||
SfizzVstProcessor();
|
||||
~SfizzVstProcessor();
|
||||
|
||||
tresult PLUGIN_API initialize(FUnknown* context) override;
|
||||
tresult PLUGIN_API setBusArrangements(Vst::SpeakerArrangement* inputs, int32 numIns, Vst::SpeakerArrangement* outputs, int32 numOuts) override;
|
||||
|
||||
tresult PLUGIN_API setState(IBStream* state) override;
|
||||
tresult PLUGIN_API getState(IBStream* state) override;
|
||||
|
||||
tresult PLUGIN_API canProcessSampleSize(int32 symbolicSampleSize) override;
|
||||
tresult PLUGIN_API setActive(TBool state) override;
|
||||
tresult PLUGIN_API process(Vst::ProcessData& data) override;
|
||||
|
||||
tresult PLUGIN_API notify(Vst::IMessage* message) override;
|
||||
|
||||
static FUnknown* createInstance(void*);
|
||||
|
||||
static FUID cid;
|
||||
|
||||
// --- Sfizz stuff here below ---
|
||||
private:
|
||||
std::unique_ptr<sfz::Sfizz> _synth;
|
||||
std::thread _worker;
|
||||
volatile bool _workRunning = false;
|
||||
Steinberg::OneReaderOneWriter::RingBuffer<Vst::IMessage*> _fifoToWorker;
|
||||
RTSemaphore _semaToWorker;
|
||||
std::mutex _processMutex;
|
||||
|
||||
// state
|
||||
std::string _sfzFile;
|
||||
|
||||
//
|
||||
void loadSfzFile(std::string file);
|
||||
|
||||
// worker
|
||||
void doBackgroundWork();
|
||||
void stopBackgroundWork();
|
||||
};
|
||||
42
vst/SfizzVstState.cpp
Normal file
42
vst/SfizzVstState.cpp
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// 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 "SfizzVstState.h"
|
||||
#include <mutex>
|
||||
#include <cstring>
|
||||
|
||||
tresult SfizzVstState::load(IBStream* state)
|
||||
{
|
||||
IBStreamer s(state, kLittleEndian);
|
||||
|
||||
uint64 version = 0;
|
||||
if (!s.readInt64u(version))
|
||||
return kResultFalse;
|
||||
|
||||
while (const char* key = s.readStr8()) {
|
||||
if (!std::strcmp(key, "SfzFile")) {
|
||||
const char* value = s.readStr8();
|
||||
if (!value)
|
||||
return kResultFalse;
|
||||
sfzFile = value;
|
||||
}
|
||||
}
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
|
||||
tresult SfizzVstState::store(IBStream* state) const
|
||||
{
|
||||
IBStreamer s(state, kLittleEndian);
|
||||
|
||||
if (!s.writeInt64u(currentStateVersion))
|
||||
return kResultFalse;
|
||||
|
||||
if (!s.writeStr8("SfzFile") || !s.writeStr8(sfzFile.c_str()))
|
||||
return kResultFalse;
|
||||
|
||||
return kResultTrue;
|
||||
}
|
||||
21
vst/SfizzVstState.h
Normal file
21
vst/SfizzVstState.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// 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 "base/source/fstreamer.h"
|
||||
#include <string>
|
||||
|
||||
using namespace Steinberg;
|
||||
|
||||
class SfizzVstState {
|
||||
public:
|
||||
std::string sfzFile;
|
||||
|
||||
static constexpr uint64 currentStateVersion = 0;
|
||||
|
||||
tresult load(IBStream* state);
|
||||
tresult store(IBStream* state) const;
|
||||
};
|
||||
11
vst/VstPluginDefs.h.in
Normal file
11
vst/VstPluginDefs.h.in
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// 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
|
||||
|
||||
#define VSTPLUGIN_NAME "@VSTPLUGIN_NAME@"
|
||||
#define VSTPLUGIN_VENDOR "@VSTPLUGIN_VENDOR@"
|
||||
#define VSTPLUGIN_URL "@VSTPLUGIN_URL@"
|
||||
#define VSTPLUGIN_EMAIL "@VSTPLUGIN_EMAIL@"
|
||||
#define VSTPLUGIN_VERSION "@PROJECT_VERSION@"
|
||||
49
vst/VstPluginFactory.cpp
Normal file
49
vst/VstPluginFactory.cpp
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
// 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 "SfizzVstProcessor.h"
|
||||
#include "SfizzVstController.h"
|
||||
#include "VstPluginDefs.h"
|
||||
#include "public.sdk/source/main/pluginfactory.h"
|
||||
#include "pluginterfaces/vst/ivstcomponent.h"
|
||||
#include "pluginterfaces/vst/ivstaudioprocessor.h"
|
||||
#include "pluginterfaces/vst/ivsteditcontroller.h"
|
||||
|
||||
BEGIN_FACTORY_DEF(VSTPLUGIN_VENDOR,
|
||||
VSTPLUGIN_URL,
|
||||
"mailto:" VSTPLUGIN_EMAIL)
|
||||
|
||||
DEF_CLASS2 (INLINE_UID_FROM_FUID(SfizzVstProcessor::cid),
|
||||
PClassInfo::kManyInstances,
|
||||
kVstAudioEffectClass,
|
||||
VSTPLUGIN_NAME,
|
||||
Vst::kDistributable,
|
||||
Vst::PlugType::kInstrumentSynth,
|
||||
VSTPLUGIN_VERSION,
|
||||
kVstVersionString,
|
||||
SfizzVstProcessor::createInstance)
|
||||
|
||||
DEF_CLASS2 (INLINE_UID_FROM_FUID(SfizzVstController::cid),
|
||||
PClassInfo::kManyInstances,
|
||||
kVstComponentControllerClass,
|
||||
VSTPLUGIN_NAME,
|
||||
0, // not used here
|
||||
"", // not used here
|
||||
VSTPLUGIN_VERSION,
|
||||
kVstVersionString,
|
||||
SfizzVstController::createInstance)
|
||||
|
||||
END_FACTORY
|
||||
|
||||
bool InitModule()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeinitModule()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
244
vst/cmake/Vst3.cmake
Normal file
244
vst/cmake/Vst3.cmake
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
find_package(Threads REQUIRED)
|
||||
|
||||
# --- VST3SDK ---
|
||||
function(plugin_add_vst3sdk NAME)
|
||||
target_sources("${NAME}" PRIVATE
|
||||
"${VST3SDK_BASEDIR}/base/source/baseiids.cpp"
|
||||
"${VST3SDK_BASEDIR}/base/source/fbuffer.cpp"
|
||||
"${VST3SDK_BASEDIR}/base/source/fdebug.cpp"
|
||||
"${VST3SDK_BASEDIR}/base/source/fdynlib.cpp"
|
||||
"${VST3SDK_BASEDIR}/base/source/fobject.cpp"
|
||||
"${VST3SDK_BASEDIR}/base/source/fstreamer.cpp"
|
||||
"${VST3SDK_BASEDIR}/base/source/fstring.cpp"
|
||||
# "${VST3SDK_BASEDIR}/base/source/timer.cpp"
|
||||
"${VST3SDK_BASEDIR}/base/source/updatehandler.cpp"
|
||||
"${VST3SDK_BASEDIR}/base/thread/source/fcondition.cpp"
|
||||
"${VST3SDK_BASEDIR}/base/thread/source/flock.cpp"
|
||||
"${VST3SDK_BASEDIR}/pluginterfaces/base/conststringtable.cpp"
|
||||
"${VST3SDK_BASEDIR}/pluginterfaces/base/coreiids.cpp"
|
||||
"${VST3SDK_BASEDIR}/pluginterfaces/base/funknown.cpp"
|
||||
"${VST3SDK_BASEDIR}/pluginterfaces/base/ustring.cpp"
|
||||
"${VST3SDK_BASEDIR}/public.sdk/source/common/commoniids.cpp"
|
||||
"${VST3SDK_BASEDIR}/public.sdk/source/common/pluginview.cpp"
|
||||
"${VST3SDK_BASEDIR}/public.sdk/source/main/pluginfactory.cpp"
|
||||
"${VST3SDK_BASEDIR}/public.sdk/source/vst/vstaudioeffect.cpp"
|
||||
"${VST3SDK_BASEDIR}/public.sdk/source/vst/vstbus.cpp"
|
||||
"${VST3SDK_BASEDIR}/public.sdk/source/vst/vstcomponent.cpp"
|
||||
"${VST3SDK_BASEDIR}/public.sdk/source/vst/vstcomponentbase.cpp"
|
||||
"${VST3SDK_BASEDIR}/public.sdk/source/vst/vsteditcontroller.cpp"
|
||||
"${VST3SDK_BASEDIR}/public.sdk/source/vst/vstinitiids.cpp"
|
||||
"${VST3SDK_BASEDIR}/public.sdk/source/vst/vstnoteexpressiontypes.cpp"
|
||||
"${VST3SDK_BASEDIR}/public.sdk/source/vst/vstparameters.cpp"
|
||||
"${VST3SDK_BASEDIR}/public.sdk/source/vst/vstpresetfile.cpp"
|
||||
"${VST3SDK_BASEDIR}/public.sdk/source/vst/vstrepresentation.cpp")
|
||||
if(WIN32)
|
||||
target_sources("${NAME}" PRIVATE
|
||||
"${VST3SDK_BASEDIR}/public.sdk/source/common/threadchecker_win32.cpp"
|
||||
"${VST3SDK_BASEDIR}/public.sdk/source/vst/vstgui_win32_bundle_support.cpp"
|
||||
"${VST3SDK_BASEDIR}/public.sdk/source/main/dllmain.cpp")
|
||||
elseif(APPLE)
|
||||
target_sources("${NAME}" PRIVATE
|
||||
"${VST3SDK_BASEDIR}/public.sdk/source/main/macmain.cpp")
|
||||
else()
|
||||
target_sources("${NAME}" PRIVATE
|
||||
"${VST3SDK_BASEDIR}/public.sdk/source/common/threadchecker_linux.cpp"
|
||||
"${VST3SDK_BASEDIR}/public.sdk/source/main/linuxmain.cpp")
|
||||
endif()
|
||||
target_include_directories("${NAME}" PRIVATE "${VST3SDK_BASEDIR}")
|
||||
target_link_libraries("${NAME}" PRIVATE Threads::Threads)
|
||||
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)
|
||||
#
|
||||
elseif(APPLE)
|
||||
#
|
||||
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)
|
||||
endfunction()
|
||||
|
||||
# --- VST3 Bundle architecture ---
|
||||
if(NOT VST3_PACKAGE_ARCHITECTURE)
|
||||
if(APPLE)
|
||||
# VST3 packages are universal on Apple, architecture string not needed
|
||||
else()
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
|
||||
set(VST3_PACKAGE_ARCHITECTURE "x86_64")
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^i.86$")
|
||||
if(WIN32)
|
||||
set(VST3_PACKAGE_ARCHITECTURE "x86")
|
||||
else()
|
||||
set(VST3_PACKAGE_ARCHITECTURE "i386")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "We don't know this architecture for VST3: ${CMAKE_SYSTEM_PROCESSOR}.")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
27
vst/external/steinberg/LICENSE
vendored
Normal file
27
vst/external/steinberg/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// VSTGUI LICENSE
|
||||
// (c) 2018, Steinberg Media Technologies, All Rights Reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Steinberg Media Technologies nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
// OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//-----------------------------------------------------------------------------
|
||||
110
vst/external/steinberg/src/x11runloop.h
vendored
Normal file
110
vst/external/steinberg/src/x11runloop.h
vendored
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
#include "vstgui/lib/platform/linux/x11frame.h"
|
||||
#include "pluginterfaces/gui/iplugview.h"
|
||||
#include "base/source/fstring.h"
|
||||
|
||||
namespace VSTGUI {
|
||||
|
||||
// Map Steinberg Vst Interface to VSTGUI Interface
|
||||
class RunLoop : public X11::IRunLoop, public AtomicReferenceCounted
|
||||
{
|
||||
public:
|
||||
struct EventHandler : Steinberg::Linux::IEventHandler, public Steinberg::FObject
|
||||
{
|
||||
X11::IEventHandler* handler {nullptr};
|
||||
|
||||
void PLUGIN_API onFDIsSet (Steinberg::Linux::FileDescriptor) override
|
||||
{
|
||||
if (handler)
|
||||
handler->onEvent ();
|
||||
}
|
||||
DELEGATE_REFCOUNT (Steinberg::FObject)
|
||||
DEFINE_INTERFACES
|
||||
DEF_INTERFACE (Steinberg::Linux::IEventHandler)
|
||||
END_DEFINE_INTERFACES (Steinberg::FObject)
|
||||
};
|
||||
struct TimerHandler : Steinberg::Linux::ITimerHandler, public Steinberg::FObject
|
||||
{
|
||||
X11::ITimerHandler* handler {nullptr};
|
||||
|
||||
void PLUGIN_API onTimer () final
|
||||
{
|
||||
if (handler)
|
||||
handler->onTimer ();
|
||||
}
|
||||
DELEGATE_REFCOUNT (Steinberg::FObject)
|
||||
DEFINE_INTERFACES
|
||||
DEF_INTERFACE (Steinberg::Linux::ITimerHandler)
|
||||
END_DEFINE_INTERFACES (Steinberg::FObject)
|
||||
};
|
||||
|
||||
bool registerEventHandler (int fd, X11::IEventHandler* handler) final
|
||||
{
|
||||
if(!runLoop)
|
||||
return false;
|
||||
|
||||
auto smtgHandler = Steinberg::owned (new EventHandler ());
|
||||
smtgHandler->handler = handler;
|
||||
if (runLoop->registerEventHandler (smtgHandler, fd) == Steinberg::kResultTrue)
|
||||
{
|
||||
eventHandlers.push_back (smtgHandler);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool unregisterEventHandler (X11::IEventHandler* handler) final
|
||||
{
|
||||
if(!runLoop)
|
||||
return false;
|
||||
|
||||
for (auto it = eventHandlers.begin (), end = eventHandlers.end (); it != end; ++it)
|
||||
{
|
||||
if ((*it)->handler == handler)
|
||||
{
|
||||
runLoop->unregisterEventHandler ((*it));
|
||||
eventHandlers.erase (it);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool registerTimer (uint64_t interval, X11::ITimerHandler* handler) final
|
||||
{
|
||||
if(!runLoop)
|
||||
return false;
|
||||
|
||||
auto smtgHandler = Steinberg::owned (new TimerHandler ());
|
||||
smtgHandler->handler = handler;
|
||||
if (runLoop->registerTimer (smtgHandler, interval) == Steinberg::kResultTrue)
|
||||
{
|
||||
timerHandlers.push_back (smtgHandler);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool unregisterTimer (X11::ITimerHandler* handler) final
|
||||
{
|
||||
if(!runLoop)
|
||||
return false;
|
||||
|
||||
for (auto it = timerHandlers.begin (), end = timerHandlers.end (); it != end; ++it)
|
||||
{
|
||||
if ((*it)->handler == handler)
|
||||
{
|
||||
runLoop->unregisterTimer ((*it));
|
||||
timerHandlers.erase (it);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
RunLoop (Steinberg::FUnknown* runLoop) : runLoop (runLoop) {}
|
||||
private:
|
||||
using EventHandlers = std::vector<Steinberg::IPtr<EventHandler>>;
|
||||
using TimerHandlers = std::vector<Steinberg::IPtr<TimerHandler>>;
|
||||
EventHandlers eventHandlers;
|
||||
TimerHandlers timerHandlers;
|
||||
Steinberg::FUnknownPtr<Steinberg::Linux::IRunLoop> runLoop;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
7
vst/vst3.version
Normal file
7
vst/vst3.version
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
VST3ABI_1.0 {
|
||||
global:
|
||||
*GetPluginFactory*;
|
||||
*ModuleEntry*;
|
||||
*ModuleExit*;
|
||||
local: *;
|
||||
};
|
||||
Loading…
Add table
Reference in a new issue