2022-02-17 06:23:22 +11:00
|
|
|
use std::ops::Deref;
|
|
|
|
use vst3_sys::{interfaces::IUnknown, ComInterface};
|
2022-02-07 03:50:15 +11:00
|
|
|
|
2022-04-09 04:53:32 +10:00
|
|
|
/// When `Plugin::MIDI_INPUT` is set to `MidiConfig::MidiCCs` or higher then we'll register 130*16
|
|
|
|
/// additional parameters to handle MIDI CCs, channel pressure, and pitch bend, in that order.
|
|
|
|
/// vst3-sys doesn't expose these constants.
|
|
|
|
pub const VST3_MIDI_CCS: u32 = 130;
|
|
|
|
pub const VST3_MIDI_CHANNELS: u32 = 16;
|
|
|
|
/// The number of parameters we'll need to register if the plugin accepts MIDI CCs.
|
|
|
|
pub const VST3_MIDI_NUM_PARAMS: u32 = VST3_MIDI_CCS * VST3_MIDI_CHANNELS;
|
|
|
|
/// The start of the MIDI CC parameter ranges. We'll print an assertion failure if any of the
|
|
|
|
/// plugin's parameters overlap with this range. The mapping to a parameter index is
|
|
|
|
/// `VST3_MIDI_PARAMS_START + (cc_idx + (channel * VST3_MIDI_CCS))`.
|
|
|
|
pub const VST3_MIDI_PARAMS_START: u32 = VST3_MIDI_PARAMS_END - VST3_MIDI_NUM_PARAMS;
|
|
|
|
/// The (exlucive) end of the MIDI CC parameter range. Anything above this is reserved by the host.
|
|
|
|
pub const VST3_MIDI_PARAMS_END: u32 = (1 << 31) + 1;
|
|
|
|
|
2022-02-07 03:40:35 +11:00
|
|
|
/// Early exit out of a VST3 function when one of the passed pointers is null
|
|
|
|
macro_rules! check_null_ptr {
|
|
|
|
($ptr:expr $(, $ptrs:expr)* $(, )?) => {
|
|
|
|
check_null_ptr_msg!("Null pointer passed to function", $ptr $(, $ptrs)*)
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-03-04 09:05:01 +11:00
|
|
|
/// The same as [`check_null_ptr!`], but with a custom message.
|
2022-02-07 03:40:35 +11:00
|
|
|
macro_rules! check_null_ptr_msg {
|
|
|
|
($msg:expr, $ptr:expr $(, $ptrs:expr)* $(, )?) => {
|
|
|
|
if $ptr.is_null() $(|| $ptrs.is_null())* {
|
|
|
|
nih_debug_assert_failure!($msg);
|
|
|
|
return kInvalidArgument;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2022-02-07 03:50:15 +11:00
|
|
|
|
|
|
|
/// Send+Sync wrapper for these interface pointers.
|
|
|
|
#[repr(transparent)]
|
|
|
|
pub struct VstPtr<T: vst3_sys::ComInterface + ?Sized> {
|
|
|
|
ptr: vst3_sys::VstPtr<T>,
|
|
|
|
}
|
|
|
|
|
2022-03-04 09:05:01 +11:00
|
|
|
/// The same as [`VstPtr`] with shared semnatics, but for objects we defined ourself since VstPtr
|
|
|
|
/// only works for interfaces.
|
2022-02-17 06:23:22 +11:00
|
|
|
#[repr(transparent)]
|
|
|
|
pub struct ObjectPtr<T: IUnknown> {
|
|
|
|
ptr: *const T,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: ComInterface + ?Sized> Deref for VstPtr<T> {
|
2022-02-07 03:50:15 +11:00
|
|
|
type Target = vst3_sys::VstPtr<T>;
|
|
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
&self.ptr
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-17 06:23:22 +11:00
|
|
|
impl<T: IUnknown> Deref for ObjectPtr<T> {
|
|
|
|
type Target = T;
|
|
|
|
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
|
|
unsafe { &*self.ptr }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-07 03:50:15 +11:00
|
|
|
impl<T: vst3_sys::ComInterface + ?Sized> From<vst3_sys::VstPtr<T>> for VstPtr<T> {
|
|
|
|
fn from(ptr: vst3_sys::VstPtr<T>) -> Self {
|
|
|
|
Self { ptr }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-17 06:43:53 +11:00
|
|
|
impl<T: IUnknown> From<&T> for ObjectPtr<T> {
|
|
|
|
/// Create a smart pointer for an existing reference counted object.
|
|
|
|
fn from(obj: &T) -> Self {
|
|
|
|
unsafe { obj.add_ref() };
|
|
|
|
Self { ptr: obj }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-17 06:23:22 +11:00
|
|
|
impl<T: IUnknown> Drop for ObjectPtr<T> {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
unsafe { (*self).release() };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-07 03:50:15 +11:00
|
|
|
/// SAFETY: Sharing these pointers across thread is s safe as they have internal atomic reference
|
|
|
|
/// counting, so as long as a `VstPtr<T>` handle exists the object will stay alive.
|
2022-02-17 06:23:22 +11:00
|
|
|
unsafe impl<T: ComInterface + ?Sized> Send for VstPtr<T> {}
|
|
|
|
unsafe impl<T: ComInterface + ?Sized> Sync for VstPtr<T> {}
|
|
|
|
|
|
|
|
unsafe impl<T: IUnknown> Send for ObjectPtr<T> {}
|
|
|
|
unsafe impl<T: IUnknown> Sync for ObjectPtr<T> {}
|