diff --git a/src/wrapper/vst3.rs b/src/wrapper/vst3.rs index 1f7fd923..47e25651 100644 --- a/src/wrapper/vst3.rs +++ b/src/wrapper/vst3.rs @@ -14,158 +14,17 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -use std::ffi::c_void; -use std::marker::PhantomData; -use std::mem; -use vst3_sys::base::{kInvalidArgument, kNoInterface, kResultOk, tresult}; -use vst3_sys::base::{IPluginFactory, IPluginFactory2, IPluginFactory3}; -use vst3_sys::VST3; - -mod context; -mod inner; #[macro_use] mod util; + +mod context; +mod factory; +mod inner; mod view; mod wrapper; -use self::wrapper::Wrapper; -use crate::plugin::Vst3Plugin; -use crate::wrapper::util::{strlcpy, u16strlcpy}; - -// Alias needed for the VST3 attribute macro -use vst3_sys as vst3_com; - /// Re-export for the wrapper. -pub use vst3_sys::sys::GUID; - -/// The VST3 SDK version this is roughtly based on. -const VST3_SDK_VERSION: &str = "VST 3.6.14"; - -#[doc(hidden)] -#[VST3(implements(IPluginFactory, IPluginFactory2, IPluginFactory3))] -pub struct Factory { - /// The type will be used for constructing plugin instances later. - _phantom: PhantomData

, -} - -impl Factory

{ - pub fn new() -> Box { - Self::allocate(PhantomData::default()) - } -} - -impl IPluginFactory for Factory

{ - unsafe fn get_factory_info(&self, info: *mut vst3_sys::base::PFactoryInfo) -> tresult { - *info = mem::zeroed(); - - let info = &mut *info; - strlcpy(&mut info.vendor, P::VENDOR); - strlcpy(&mut info.url, P::URL); - strlcpy(&mut info.email, P::EMAIL); - info.flags = vst3_sys::base::FactoryFlags::kUnicode as i32; - - kResultOk - } - - unsafe fn count_classes(&self) -> i32 { - // We don't do shell plugins, and good of an idea having separated components and edit - // controllers in theory is, few software can use it, and doing that would make our simple - // microframework a lot less simple - 1 - } - - unsafe fn get_class_info(&self, index: i32, info: *mut vst3_sys::base::PClassInfo) -> tresult { - if index != 0 { - return kInvalidArgument; - } - - *info = mem::zeroed(); - - let info = &mut *info; - info.cid.data = P::VST3_CLASS_ID; - info.cardinality = vst3_sys::base::ClassCardinality::kManyInstances as i32; - strlcpy(&mut info.category, "Audio Module Class"); - strlcpy(&mut info.name, P::NAME); - - kResultOk - } - - unsafe fn create_instance( - &self, - cid: *const vst3_sys::IID, - _iid: *const vst3_sys::IID, - obj: *mut *mut vst3_sys::c_void, - ) -> tresult { - check_null_ptr!(cid, obj); - - if (*cid).data != P::VST3_CLASS_ID { - return kNoInterface; - } - - *obj = Box::into_raw(Wrapper::

::new()) as *mut vst3_sys::c_void; - - kResultOk - } -} - -impl IPluginFactory2 for Factory

{ - unsafe fn get_class_info2( - &self, - index: i32, - info: *mut vst3_sys::base::PClassInfo2, - ) -> tresult { - if index != 0 { - return kInvalidArgument; - } - - *info = mem::zeroed(); - - let info = &mut *info; - info.cid.data = P::VST3_CLASS_ID; - info.cardinality = vst3_sys::base::ClassCardinality::kManyInstances as i32; - strlcpy(&mut info.category, "Audio Module Class"); - strlcpy(&mut info.name, P::NAME); - info.class_flags = 1 << 1; // kSimpleModeSupported - strlcpy(&mut info.subcategories, P::VST3_CATEGORIES); - strlcpy(&mut info.vendor, P::VENDOR); - strlcpy(&mut info.version, P::VERSION); - strlcpy(&mut info.sdk_version, VST3_SDK_VERSION); - - kResultOk - } -} - -impl IPluginFactory3 for Factory

{ - unsafe fn get_class_info_unicode( - &self, - index: i32, - info: *mut vst3_sys::base::PClassInfoW, - ) -> tresult { - if index != 0 { - return kInvalidArgument; - } - - *info = mem::zeroed(); - - let info = &mut *info; - info.cid.data = P::VST3_CLASS_ID; - info.cardinality = vst3_sys::base::ClassCardinality::kManyInstances as i32; - strlcpy(&mut info.category, "Audio Module Class"); - u16strlcpy(&mut info.name, P::NAME); - info.class_flags = 1 << 1; // kSimpleModeSupported - strlcpy(&mut info.subcategories, P::VST3_CATEGORIES); - u16strlcpy(&mut info.vendor, P::VENDOR); - u16strlcpy(&mut info.version, P::VERSION); - u16strlcpy(&mut info.sdk_version, VST3_SDK_VERSION); - - kResultOk - } - - unsafe fn set_host_context(&self, _context: *mut c_void) -> tresult { - // We don't need to do anything with this - kResultOk - } -} +pub use factory::Factory; /// Export a VST3 plugin from this library using the provided plugin type. #[macro_export] diff --git a/src/wrapper/vst3/factory.rs b/src/wrapper/vst3/factory.rs new file mode 100644 index 00000000..101bc068 --- /dev/null +++ b/src/wrapper/vst3/factory.rs @@ -0,0 +1,158 @@ +// nih-plug: plugins, but rewritten in Rust +// Copyright (C) 2022 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 . + +use std::ffi::c_void; +use std::marker::PhantomData; +use std::mem; +use vst3_sys::base::{kInvalidArgument, kNoInterface, kResultOk, tresult}; +use vst3_sys::base::{IPluginFactory, IPluginFactory2, IPluginFactory3}; +use vst3_sys::VST3; + +// Alias needed for the VST3 attribute macro +use vst3_sys as vst3_com; + +use super::wrapper::Wrapper; +use crate::plugin::Vst3Plugin; +use crate::wrapper::util::{strlcpy, u16strlcpy}; + +/// The VST3 SDK version this is roughtly based on. +const VST3_SDK_VERSION: &str = "VST 3.6.14"; + +#[doc(hidden)] +#[VST3(implements(IPluginFactory, IPluginFactory2, IPluginFactory3))] +pub struct Factory { + /// The type will be used for constructing plugin instances later. + _phantom: PhantomData

, +} + +impl Factory

{ + pub fn new() -> Box { + Self::allocate(PhantomData::default()) + } +} + +impl IPluginFactory for Factory

{ + unsafe fn get_factory_info(&self, info: *mut vst3_sys::base::PFactoryInfo) -> tresult { + *info = mem::zeroed(); + + let info = &mut *info; + strlcpy(&mut info.vendor, P::VENDOR); + strlcpy(&mut info.url, P::URL); + strlcpy(&mut info.email, P::EMAIL); + info.flags = vst3_sys::base::FactoryFlags::kUnicode as i32; + + kResultOk + } + + unsafe fn count_classes(&self) -> i32 { + // We don't do shell plugins, and good of an idea having separated components and edit + // controllers in theory is, few software can use it, and doing that would make our simple + // microframework a lot less simple + 1 + } + + unsafe fn get_class_info(&self, index: i32, info: *mut vst3_sys::base::PClassInfo) -> tresult { + if index != 0 { + return kInvalidArgument; + } + + *info = mem::zeroed(); + + let info = &mut *info; + info.cid.data = P::VST3_CLASS_ID; + info.cardinality = vst3_sys::base::ClassCardinality::kManyInstances as i32; + strlcpy(&mut info.category, "Audio Module Class"); + strlcpy(&mut info.name, P::NAME); + + kResultOk + } + + unsafe fn create_instance( + &self, + cid: *const vst3_sys::IID, + _iid: *const vst3_sys::IID, + obj: *mut *mut vst3_sys::c_void, + ) -> tresult { + check_null_ptr!(cid, obj); + + if (*cid).data != P::VST3_CLASS_ID { + return kNoInterface; + } + + *obj = Box::into_raw(Wrapper::

::new()) as *mut vst3_sys::c_void; + + kResultOk + } +} + +impl IPluginFactory2 for Factory

{ + unsafe fn get_class_info2( + &self, + index: i32, + info: *mut vst3_sys::base::PClassInfo2, + ) -> tresult { + if index != 0 { + return kInvalidArgument; + } + + *info = mem::zeroed(); + + let info = &mut *info; + info.cid.data = P::VST3_CLASS_ID; + info.cardinality = vst3_sys::base::ClassCardinality::kManyInstances as i32; + strlcpy(&mut info.category, "Audio Module Class"); + strlcpy(&mut info.name, P::NAME); + info.class_flags = 1 << 1; // kSimpleModeSupported + strlcpy(&mut info.subcategories, P::VST3_CATEGORIES); + strlcpy(&mut info.vendor, P::VENDOR); + strlcpy(&mut info.version, P::VERSION); + strlcpy(&mut info.sdk_version, VST3_SDK_VERSION); + + kResultOk + } +} + +impl IPluginFactory3 for Factory

{ + unsafe fn get_class_info_unicode( + &self, + index: i32, + info: *mut vst3_sys::base::PClassInfoW, + ) -> tresult { + if index != 0 { + return kInvalidArgument; + } + + *info = mem::zeroed(); + + let info = &mut *info; + info.cid.data = P::VST3_CLASS_ID; + info.cardinality = vst3_sys::base::ClassCardinality::kManyInstances as i32; + strlcpy(&mut info.category, "Audio Module Class"); + u16strlcpy(&mut info.name, P::NAME); + info.class_flags = 1 << 1; // kSimpleModeSupported + strlcpy(&mut info.subcategories, P::VST3_CATEGORIES); + u16strlcpy(&mut info.vendor, P::VENDOR); + u16strlcpy(&mut info.version, P::VERSION); + u16strlcpy(&mut info.sdk_version, VST3_SDK_VERSION); + + kResultOk + } + + unsafe fn set_host_context(&self, _context: *mut c_void) -> tresult { + // We don't need to do anything with this + kResultOk + } +}