mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-07 03:50:11 +02:00
4f8eaaaa75
Now every proxy object that's directly created by the host or plugin shares the same structure.
225 lines
9.7 KiB
C++
225 lines
9.7 KiB
C++
// yabridge: a Wine VST bridge
|
|
// Copyright (C) 2020-2021 Robbert van der Helm
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
#pragma once
|
|
|
|
#include <variant>
|
|
|
|
#include <bitsery/ext/std_variant.h>
|
|
|
|
#include "../configuration.h"
|
|
#include "../utils.h"
|
|
#include "common.h"
|
|
#include "vst3/component-handler-proxy.h"
|
|
#include "vst3/connection-point-proxy.h"
|
|
#include "vst3/context-menu-proxy.h"
|
|
#include "vst3/context-menu-target.h"
|
|
#include "vst3/host-context-proxy.h"
|
|
#include "vst3/plug-frame-proxy.h"
|
|
#include "vst3/plug-view-proxy.h"
|
|
#include "vst3/plugin-factory-proxy.h"
|
|
#include "vst3/plugin-proxy.h"
|
|
|
|
// Event handling for our VST3 plugins works slightly different from how we
|
|
// handle VST2 plugins. VST3 does not have a centralized event dispatching
|
|
// interface like VST2 does, and it uses a bunch of separate interfaces instead.
|
|
// Instead of having an a single event/result with accompanying payload values
|
|
// for both host -> plugin `dispatcher()` and plugin -> host `audioMaster()`
|
|
// calls, we'll send objects of type `T` that should receive a response of type
|
|
// `T::Response`, where all of the possible `T`s are stored in an
|
|
// `std::variant`. This way we communicate in a completely type safe way.
|
|
|
|
// TODO: If this approach works, maybe we can also refactor the VST2 handling to
|
|
// do this since it's a bit safer and easier to read
|
|
|
|
// All messages for creating objects and calling interfaces on them are defined
|
|
// as part of the interfaces and implementations in `vst3/`
|
|
|
|
/**
|
|
* Marker struct to indicate the other side (the plugin) should send a copy of
|
|
* the configuration.
|
|
*/
|
|
struct WantsConfiguration {
|
|
using Response = Configuration;
|
|
|
|
template <typename S>
|
|
void serialize(S&) {}
|
|
};
|
|
|
|
/**
|
|
* When we send a control message from the plugin to the Wine VST host, this
|
|
* encodes the information we request or the operation we want to perform. A
|
|
* request of type `ControlRequest(T)` should send back a `T::Response`.
|
|
*/
|
|
using ControlRequest =
|
|
std::variant<Vst3PluginFactoryProxy::Construct,
|
|
Vst3PlugViewProxy::Destruct,
|
|
Vst3PluginProxy::Construct,
|
|
Vst3PluginProxy::Destruct,
|
|
Vst3PluginProxy::SetState,
|
|
Vst3PluginProxy::GetState,
|
|
YaAudioPresentationLatency::SetAudioPresentationLatencySamples,
|
|
YaAutomationState::SetAutomationState,
|
|
YaConnectionPoint::Connect,
|
|
YaConnectionPoint::Disconnect,
|
|
YaConnectionPoint::Notify,
|
|
YaContextMenuTarget::ExecuteMenuItem,
|
|
YaEditController::SetComponentState,
|
|
YaEditController::GetParameterCount,
|
|
YaEditController::GetParameterInfo,
|
|
YaEditController::GetParamStringByValue,
|
|
YaEditController::GetParamValueByString,
|
|
YaEditController::NormalizedParamToPlain,
|
|
YaEditController::PlainParamToNormalized,
|
|
YaEditController::GetParamNormalized,
|
|
YaEditController::SetParamNormalized,
|
|
YaEditController::SetComponentHandler,
|
|
YaEditController::CreateView,
|
|
YaEditController2::SetKnobMode,
|
|
YaEditController2::OpenHelp,
|
|
YaEditController2::OpenAboutBox,
|
|
YaEditControllerHostEditing::BeginEditFromHost,
|
|
YaEditControllerHostEditing::EndEditFromHost,
|
|
YaInfoListener::SetChannelContextInfos,
|
|
YaKeyswitchController::GetKeyswitchCount,
|
|
YaKeyswitchController::GetKeyswitchInfo,
|
|
YaMidiLearn::OnLiveMIDIControllerInput,
|
|
YaMidiMapping::GetMidiControllerAssignment,
|
|
YaNoteExpressionController::GetNoteExpressionCount,
|
|
YaNoteExpressionController::GetNoteExpressionInfo,
|
|
YaNoteExpressionController::GetNoteExpressionStringByValue,
|
|
YaNoteExpressionController::GetNoteExpressionValueByString,
|
|
YaNoteExpressionPhysicalUIMapping::GetNotePhysicalUIMapping,
|
|
YaParameterFinder::FindParameter,
|
|
YaParameterFunctionName::GetParameterIDFromFunctionName,
|
|
YaPlugView::IsPlatformTypeSupported,
|
|
YaPlugView::Attached,
|
|
YaPlugView::Removed,
|
|
YaPlugView::OnWheel,
|
|
YaPlugView::OnKeyDown,
|
|
YaPlugView::OnKeyUp,
|
|
YaPlugView::GetSize,
|
|
YaPlugView::OnSize,
|
|
YaPlugView::OnFocus,
|
|
YaPlugView::SetFrame,
|
|
YaPlugView::CanResize,
|
|
YaPlugView::CheckSizeConstraint,
|
|
YaPlugViewContentScaleSupport::SetContentScaleFactor,
|
|
YaPluginBase::Initialize,
|
|
YaPluginBase::Terminate,
|
|
YaPluginFactory3::SetHostContext,
|
|
YaProcessContextRequirements::GetProcessContextRequirements,
|
|
YaProgramListData::ProgramDataSupported,
|
|
YaProgramListData::GetProgramData,
|
|
YaProgramListData::SetProgramData,
|
|
YaUnitData::UnitDataSupported,
|
|
YaUnitData::GetUnitData,
|
|
YaUnitData::SetUnitData,
|
|
YaUnitInfo::GetUnitCount,
|
|
YaUnitInfo::GetUnitInfo,
|
|
YaUnitInfo::GetProgramListCount,
|
|
YaUnitInfo::GetProgramListInfo,
|
|
YaUnitInfo::GetProgramName,
|
|
YaUnitInfo::GetProgramInfo,
|
|
YaUnitInfo::HasProgramPitchNames,
|
|
YaUnitInfo::GetProgramPitchName,
|
|
YaUnitInfo::GetSelectedUnit,
|
|
YaUnitInfo::SelectUnit,
|
|
YaUnitInfo::GetUnitByBus,
|
|
YaUnitInfo::SetUnitProgramData,
|
|
YaXmlRepresentationController::GetXmlRepresentationStream>;
|
|
|
|
template <typename S>
|
|
void serialize(S& s, ControlRequest& payload) {
|
|
// All of the objects in `ControlRequest` should have their own
|
|
// serialization function.
|
|
s.ext(payload, bitsery::ext::StdVariant{});
|
|
}
|
|
|
|
/**
|
|
* A subset of all functions a host can call on a plugin. These functions are
|
|
* called from a hot loop every processing cycle, so we want a dedicated socket
|
|
* for these for every plugin instance.
|
|
*/
|
|
using AudioProcessorRequest =
|
|
std::variant<YaAudioProcessor::SetBusArrangements,
|
|
YaAudioProcessor::GetBusArrangement,
|
|
YaAudioProcessor::CanProcessSampleSize,
|
|
YaAudioProcessor::GetLatencySamples,
|
|
YaAudioProcessor::SetupProcessing,
|
|
YaAudioProcessor::SetProcessing,
|
|
YaAudioProcessor::Process,
|
|
YaAudioProcessor::GetTailSamples,
|
|
YaComponent::GetControllerClassId,
|
|
YaComponent::SetIoMode,
|
|
YaComponent::GetBusCount,
|
|
YaComponent::GetBusInfo,
|
|
YaComponent::GetRoutingInfo,
|
|
YaComponent::ActivateBus,
|
|
YaComponent::SetActive,
|
|
YaPrefetchableSupport::GetPrefetchableSupport>;
|
|
|
|
template <typename S>
|
|
void serialize(S& s, AudioProcessorRequest& payload) {
|
|
// All of the objects in `AudioProcessorRequest` should have their own
|
|
// serialization function.
|
|
s.ext(payload, bitsery::ext::StdVariant{});
|
|
}
|
|
|
|
/**
|
|
* When we do a callback from the Wine VST host to the plugin, this encodes the
|
|
* information we want or the operation we want to perform. A request of type
|
|
* `CallbackRequest(T)` should send back a `T::Response`.
|
|
*/
|
|
using CallbackRequest =
|
|
std::variant<Vst3ContextMenuProxy::Destruct,
|
|
WantsConfiguration,
|
|
YaComponentHandler::BeginEdit,
|
|
YaComponentHandler::PerformEdit,
|
|
YaComponentHandler::EndEdit,
|
|
YaComponentHandler::RestartComponent,
|
|
YaComponentHandler2::SetDirty,
|
|
YaComponentHandler2::RequestOpenEditor,
|
|
YaComponentHandler2::StartGroupEdit,
|
|
YaComponentHandler2::FinishGroupEdit,
|
|
YaComponentHandler3::CreateContextMenu,
|
|
YaComponentHandlerBusActivation::RequestBusActivation,
|
|
// Used when the host uses proxy objects,
|
|
// and we have to route
|
|
// `IConnectionPoint::notify` calls through
|
|
// there
|
|
YaConnectionPoint::Notify,
|
|
YaContextMenu::GetItemCount,
|
|
YaContextMenu::AddItem,
|
|
YaContextMenu::RemoveItem,
|
|
YaContextMenu::Popup,
|
|
YaHostApplication::GetName,
|
|
YaPlugFrame::ResizeView,
|
|
YaPlugInterfaceSupport::IsPlugInterfaceSupported,
|
|
YaProgress::Start,
|
|
YaProgress::Update,
|
|
YaProgress::Finish,
|
|
YaUnitHandler::NotifyUnitSelection,
|
|
YaUnitHandler::NotifyProgramListChange,
|
|
YaUnitHandler2::NotifyUnitByBusChange>;
|
|
|
|
template <typename S>
|
|
void serialize(S& s, CallbackRequest& payload) {
|
|
// All of the objects in `CallbackRequest` should have their own
|
|
// serialization function.
|
|
s.ext(payload, bitsery::ext::StdVariant{});
|
|
}
|