From 34b416ecb661232e43085dc34b42242df4011cc2 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Sat, 22 Apr 2023 14:52:01 +0200 Subject: [PATCH] Move API-specific traits and structs to submodules --- src/plugin.rs | 81 +++------------------------------- src/plugin/clap.rs | 34 ++++++++++++++ src/plugin/vst3.rs | 44 ++++++++++++++++++ src/prelude.rs | 5 ++- src/wrapper/clap/context.rs | 2 +- src/wrapper/clap/descriptor.rs | 2 +- src/wrapper/clap/factory.rs | 2 +- src/wrapper/clap/wrapper.rs | 3 +- src/wrapper/vst3/context.rs | 2 +- src/wrapper/vst3/factory.rs | 2 +- src/wrapper/vst3/inner.rs | 3 +- src/wrapper/vst3/view.rs | 2 +- src/wrapper/vst3/wrapper.rs | 3 +- 13 files changed, 98 insertions(+), 87 deletions(-) create mode 100644 src/plugin/clap.rs create mode 100644 src/plugin/vst3.rs diff --git a/src/plugin.rs b/src/plugin.rs index 6e9d0966..4aa56f30 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -1,4 +1,5 @@ -//! Traits and structs describing plugins and editors. +//! Traits and structs describing plugins and editors. This includes extension structs for features +//! that are specific to one or more plugin-APIs. use std::sync::Arc; @@ -11,10 +12,11 @@ use crate::editor::Editor; use crate::midi::sysex::SysExMessage; use crate::midi::MidiConfig; use crate::params::Params; -use crate::wrapper::clap::features::ClapFeature; use crate::wrapper::state::PluginState; + +pub mod clap; #[cfg(feature = "vst3")] -pub use crate::wrapper::vst3::subcategories::Vst3SubCategory; +pub mod vst3; /// A function that can execute a plugin's [`BackgroundTask`][Plugin::BackgroundTask]s. A plugin can /// dispatch these tasks from the `initialize()` function, the `process()` function, or the GUI, so @@ -219,67 +221,6 @@ pub trait Plugin: Default + Send + 'static { fn deactivate(&mut self) {} } -/// Provides auxiliary metadata needed for a CLAP plugin. -pub trait ClapPlugin: Plugin { - /// A unique ID that identifies this particular plugin. This is usually in reverse domain name - /// notation, e.g. `com.manufacturer.plugin-name`. - const CLAP_ID: &'static str; - /// An optional short description for the plugin. - const CLAP_DESCRIPTION: Option<&'static str>; - /// The URL to the plugin's manual, if available. - const CLAP_MANUAL_URL: Option<&'static str>; - /// The URL to the plugin's support page, if available. - const CLAP_SUPPORT_URL: Option<&'static str>; - /// Keywords describing the plugin. The host may use this to classify the plugin in its plugin - /// browser. - const CLAP_FEATURES: &'static [ClapFeature]; - - /// If set, this informs the host about the plugin's capabilities for polyphonic modulation. - const CLAP_POLY_MODULATION_CONFIG: Option = None; -} - -/// Provides auxiliary metadata needed for a VST3 plugin. -#[cfg(feature = "vst3")] -pub trait Vst3Plugin: Plugin { - /// The unique class ID that identifies this particular plugin. You can use the - /// `*b"fooofooofooofooo"` syntax for this. - /// - /// This will be shuffled into a different byte order on Windows for project-compatibility. - const VST3_CLASS_ID: [u8; 16]; - /// One or more subcategories. The host may use these to categorize the plugin. Internally this - /// slice will be converted to a string where each character is separated by a pipe character - /// (`|`). This string has a limit of 127 characters, and anything longer than that will be - /// truncated. - const VST3_SUBCATEGORIES: &'static [Vst3SubCategory]; - - /// [`VST3_CLASS_ID`][Self::VST3_CLASS_ID`] in the correct order for the current platform so - /// projects and presets can be shared between platforms. This should not be overridden. - const PLATFORM_VST3_CLASS_ID: [u8; 16] = swap_vst3_uid_byte_order(Self::VST3_CLASS_ID); -} - -#[cfg(all(feature = "vst3", not(target_os = "windows")))] -const fn swap_vst3_uid_byte_order(uid: [u8; 16]) -> [u8; 16] { - uid -} - -#[cfg(all(feature = "vst3", target_os = "windows"))] -const fn swap_vst3_uid_byte_order(mut uid: [u8; 16]) -> [u8; 16] { - // No mutable references in const functions, so we can't use `uid.swap()` - let original_uid = uid; - - uid[0] = original_uid[3]; - uid[1] = original_uid[2]; - uid[2] = original_uid[1]; - uid[3] = original_uid[0]; - - uid[4] = original_uid[5]; - uid[5] = original_uid[4]; - uid[6] = original_uid[7]; - uid[7] = original_uid[6]; - - uid -} - /// Indicates the current situation after the plugin has processed audio. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ProcessStatus { @@ -295,15 +236,3 @@ pub enum ProcessStatus { /// infinite tail. KeepAlive, } - -/// Configuration for the plugin's polyphonic modulation options, if it supports . -pub struct PolyModulationConfig { - /// The maximum number of voices this plugin will ever use. Call the context's - /// `set_current_voice_capacity()` method during initialization or audio processing to set the - /// polyphony limit. - pub max_voice_capacity: u32, - /// If set to `true`, then the host may send note events for the same channel and key, but using - /// different voice IDs. Bitwig Studio, for instance, can use this to do voice stacking. After - /// enabling this, you should always prioritize using voice IDs to map note events to voices. - pub supports_overlapping_voices: bool, -} diff --git a/src/plugin/clap.rs b/src/plugin/clap.rs new file mode 100644 index 00000000..52eb99e7 --- /dev/null +++ b/src/plugin/clap.rs @@ -0,0 +1,34 @@ +use crate::wrapper::clap::features::ClapFeature; + +use super::Plugin; + +/// Provides auxiliary metadata needed for a CLAP plugin. +pub trait ClapPlugin: Plugin { + /// A unique ID that identifies this particular plugin. This is usually in reverse domain name + /// notation, e.g. `com.manufacturer.plugin-name`. + const CLAP_ID: &'static str; + /// An optional short description for the plugin. + const CLAP_DESCRIPTION: Option<&'static str>; + /// The URL to the plugin's manual, if available. + const CLAP_MANUAL_URL: Option<&'static str>; + /// The URL to the plugin's support page, if available. + const CLAP_SUPPORT_URL: Option<&'static str>; + /// Keywords describing the plugin. The host may use this to classify the plugin in its plugin + /// browser. + const CLAP_FEATURES: &'static [ClapFeature]; + + /// If set, this informs the host about the plugin's capabilities for polyphonic modulation. + const CLAP_POLY_MODULATION_CONFIG: Option = None; +} + +/// Configuration for the plugin's polyphonic modulation options, if it supports . +pub struct PolyModulationConfig { + /// The maximum number of voices this plugin will ever use. Call the context's + /// `set_current_voice_capacity()` method during initialization or audio processing to set the + /// polyphony limit. + pub max_voice_capacity: u32, + /// If set to `true`, then the host may send note events for the same channel and key, but using + /// different voice IDs. Bitwig Studio, for instance, can use this to do voice stacking. After + /// enabling this, you should always prioritize using voice IDs to map note events to voices. + pub supports_overlapping_voices: bool, +} diff --git a/src/plugin/vst3.rs b/src/plugin/vst3.rs new file mode 100644 index 00000000..e1d92dd8 --- /dev/null +++ b/src/plugin/vst3.rs @@ -0,0 +1,44 @@ +pub use crate::wrapper::vst3::subcategories::Vst3SubCategory; + +use super::Plugin; + +/// Provides auxiliary metadata needed for a VST3 plugin. +pub trait Vst3Plugin: Plugin { + /// The unique class ID that identifies this particular plugin. You can use the + /// `*b"fooofooofooofooo"` syntax for this. + /// + /// This will be shuffled into a different byte order on Windows for project-compatibility. + const VST3_CLASS_ID: [u8; 16]; + /// One or more subcategories. The host may use these to categorize the plugin. Internally this + /// slice will be converted to a string where each character is separated by a pipe character + /// (`|`). This string has a limit of 127 characters, and anything longer than that will be + /// truncated. + const VST3_SUBCATEGORIES: &'static [Vst3SubCategory]; + + /// [`VST3_CLASS_ID`][Self::VST3_CLASS_ID`] in the correct order for the current platform so + /// projects and presets can be shared between platforms. This should not be overridden. + const PLATFORM_VST3_CLASS_ID: [u8; 16] = swap_vst3_uid_byte_order(Self::VST3_CLASS_ID); +} + +#[cfg(not(target_os = "windows"))] +const fn swap_vst3_uid_byte_order(uid: [u8; 16]) -> [u8; 16] { + uid +} + +#[cfg(target_os = "windows")] +const fn swap_vst3_uid_byte_order(mut uid: [u8; 16]) -> [u8; 16] { + // No mutable references in const functions, so we can't use `uid.swap()` + let original_uid = uid; + + uid[0] = original_uid[3]; + uid[1] = original_uid[2]; + uid[2] = original_uid[1]; + uid[3] = original_uid[0]; + + uid[4] = original_uid[5]; + uid[5] = original_uid[4]; + uid[6] = original_uid[7]; + uid[7] = original_uid[6]; + + uid +} diff --git a/src/prelude.rs b/src/prelude.rs index c314fd55..0e0cd563 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -30,9 +30,10 @@ pub use crate::params::range::{FloatRange, IntRange}; pub use crate::params::smoothing::{AtomicF32, Smoothable, Smoother, SmoothingStyle}; pub use crate::params::Params; pub use crate::params::{BoolParam, FloatParam, IntParam, Param, ParamFlags}; +pub use crate::plugin::clap::{ClapPlugin, PolyModulationConfig}; #[cfg(feature = "vst3")] -pub use crate::plugin::Vst3Plugin; -pub use crate::plugin::{ClapPlugin, Plugin, PolyModulationConfig, ProcessStatus, TaskExecutor}; +pub use crate::plugin::vst3::Vst3Plugin; +pub use crate::plugin::{Plugin, ProcessStatus, TaskExecutor}; pub use crate::wrapper::clap::features::ClapFeature; pub use crate::wrapper::state::PluginState; #[cfg(feature = "vst3")] diff --git a/src/wrapper/clap/context.rs b/src/wrapper/clap/context.rs index 949665b0..488e38e5 100644 --- a/src/wrapper/clap/context.rs +++ b/src/wrapper/clap/context.rs @@ -11,7 +11,7 @@ use crate::context::PluginApi; use crate::event_loop::EventLoop; use crate::midi::PluginNoteEvent; use crate::params::internals::ParamPtr; -use crate::plugin::ClapPlugin; +use crate::plugin::clap::ClapPlugin; /// An [`InitContext`] implementation for the wrapper. /// diff --git a/src/wrapper/clap/descriptor.rs b/src/wrapper/clap/descriptor.rs index dbfb96e2..31985bdc 100644 --- a/src/wrapper/clap/descriptor.rs +++ b/src/wrapper/clap/descriptor.rs @@ -4,7 +4,7 @@ use std::ffi::{CStr, CString}; use std::marker::PhantomData; use std::os::raw::c_char; -use crate::plugin::ClapPlugin; +use crate::plugin::clap::ClapPlugin; /// A static descriptor for a plugin. This is used in both the descriptor and on the plugin object /// itself. diff --git a/src/wrapper/clap/factory.rs b/src/wrapper/clap/factory.rs index e6f408e5..39b1a487 100644 --- a/src/wrapper/clap/factory.rs +++ b/src/wrapper/clap/factory.rs @@ -8,7 +8,7 @@ use std::sync::Arc; use super::descriptor::PluginDescriptor; use super::wrapper::Wrapper; -use crate::plugin::ClapPlugin; +use crate::plugin::clap::ClapPlugin; /// The plugin's factory. Initialized using a lazy_static from the entry point's `get_factory()` /// function. From this point onwards we don't need to generate code with macros anymore. diff --git a/src/wrapper/clap/wrapper.rs b/src/wrapper/clap/wrapper.rs index 6ee0d2b7..d7e0cef3 100644 --- a/src/wrapper/clap/wrapper.rs +++ b/src/wrapper/clap/wrapper.rs @@ -87,7 +87,8 @@ use crate::midi::sysex::SysExMessage; use crate::midi::{MidiConfig, MidiResult, NoteEvent, PluginNoteEvent}; use crate::params::internals::ParamPtr; use crate::params::{ParamFlags, Params}; -use crate::plugin::{ClapPlugin, Plugin, ProcessStatus, TaskExecutor}; +use crate::plugin::clap::ClapPlugin; +use crate::plugin::{Plugin, ProcessStatus, TaskExecutor}; use crate::util::permit_alloc; use crate::wrapper::clap::util::{read_stream, write_stream}; use crate::wrapper::state::{self, PluginState}; diff --git a/src/wrapper/vst3/context.rs b/src/wrapper/vst3/context.rs index 14ed5847..6f9d0878 100644 --- a/src/wrapper/vst3/context.rs +++ b/src/wrapper/vst3/context.rs @@ -12,7 +12,7 @@ use crate::context::process::{ProcessContext, Transport}; use crate::context::PluginApi; use crate::midi::PluginNoteEvent; use crate::params::internals::ParamPtr; -use crate::plugin::Vst3Plugin; +use crate::plugin::vst3::Vst3Plugin; use crate::wrapper::state::PluginState; /// An [`InitContext`] implementation for the wrapper. diff --git a/src/wrapper/vst3/factory.rs b/src/wrapper/vst3/factory.rs index 8b1ae8ab..cd442308 100644 --- a/src/wrapper/vst3/factory.rs +++ b/src/wrapper/vst3/factory.rs @@ -11,7 +11,7 @@ use vst3_sys as vst3_com; use super::subcategories::Vst3SubCategory; use super::util::u16strlcpy; use super::wrapper::Wrapper; -use crate::plugin::Vst3Plugin; +use crate::plugin::vst3::Vst3Plugin; use crate::wrapper::util::strlcpy; /// The VST3 SDK version this is roughly based on. The bindings include some VST 3.7 things but not diff --git a/src/wrapper/vst3/inner.rs b/src/wrapper/vst3/inner.rs index bc4c5f8a..8394e971 100644 --- a/src/wrapper/vst3/inner.rs +++ b/src/wrapper/vst3/inner.rs @@ -22,7 +22,8 @@ use crate::event_loop::{EventLoop, MainThreadExecutor, OsEventLoop}; use crate::midi::{MidiConfig, PluginNoteEvent}; use crate::params::internals::ParamPtr; use crate::params::{ParamFlags, Params}; -use crate::plugin::{Plugin, ProcessStatus, TaskExecutor, Vst3Plugin}; +use crate::plugin::vst3::Vst3Plugin; +use crate::plugin::{Plugin, ProcessStatus, TaskExecutor}; use crate::util::permit_alloc; use crate::wrapper::state::{self, PluginState}; use crate::wrapper::util::buffer_management::BufferManager; diff --git a/src/wrapper/vst3/view.rs b/src/wrapper/vst3/view.rs index 472d1bc4..12065089 100644 --- a/src/wrapper/vst3/view.rs +++ b/src/wrapper/vst3/view.rs @@ -14,7 +14,7 @@ use vst3_sys::VST3; use super::inner::{Task, WrapperInner}; use super::util::{ObjectPtr, VstPtr}; use crate::editor::{Editor, ParentWindowHandle}; -use crate::plugin::Vst3Plugin; +use crate::plugin::vst3::Vst3Plugin; // Alias needed for the VST3 attribute macro use vst3_sys as vst3_com; diff --git a/src/wrapper/vst3/wrapper.rs b/src/wrapper/vst3/wrapper.rs index ffad5376..fca55a33 100644 --- a/src/wrapper/vst3/wrapper.rs +++ b/src/wrapper/vst3/wrapper.rs @@ -31,7 +31,8 @@ use crate::context::process::Transport; use crate::midi::sysex::SysExMessage; use crate::midi::{MidiConfig, NoteEvent}; use crate::params::ParamFlags; -use crate::plugin::{ProcessStatus, Vst3Plugin}; +use crate::plugin::vst3::Vst3Plugin; +use crate::plugin::ProcessStatus; use crate::util::permit_alloc; use crate::wrapper::state; use crate::wrapper::util::buffer_management::{BufferManager, ChannelPointers};