Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ jobs:
plugin: [again, passthru]
runs-on: ${{ matrix.os }}
name: validate
timeout-minutes: 10
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
Expand Down
2 changes: 1 addition & 1 deletion com/src/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub const COINIT_MULTITHREADED: u32 = 0x0;

/// A globally unique identifier
#[repr(C)]
#[derive(Copy, Clone, PartialEq, Eq)]
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct GUID {
/// bytes of the GUID
pub data: [u8; 16],
Expand Down
73 changes: 33 additions & 40 deletions examples/again/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,16 +255,14 @@ impl IComponent for AGainProcessor {
kResultOk
}

unsafe fn set_state(&self, state: *mut c_void) -> tresult {
unsafe fn set_state(&self, state: VstPtr<dyn IBStream>) -> tresult {
info!("Called: AGainProcessor::set_state()");

if state.is_null() {
let state = state.upgrade();
if state.is_none() {
return kResultFalse;
}

let state = state as *mut *mut _;
let state: ComPtr<dyn IBStream> = ComPtr::new(state);

let state = state.unwrap();
let mut num_bytes_read = 0;
let mut saved_gain = 0.0;
let mut saved_bypass = false;
Expand All @@ -284,16 +282,14 @@ impl IComponent for AGainProcessor {
kResultOk
}

unsafe fn get_state(&self, state: *mut c_void) -> tresult {
unsafe fn get_state(&self, state: VstPtr<dyn IBStream>) -> tresult {
info!("Called: AGainProcessor::get_state()");

if state.is_null() {
let state = state.upgrade();
if state.is_none() {
return kResultFalse;
}

let state = state as *mut *mut _;
let state: ComPtr<dyn IBStream> = ComPtr::new(state);

let state = state.unwrap();
let mut num_bytes_written = 0;
let gain_ptr = &mut self.gain.borrow_mut().0 as *mut f64 as *mut c_void;
let bypass_ptr = &mut self.bypass.borrow_mut().0 as *mut bool as *mut c_void;
Expand Down Expand Up @@ -552,43 +548,40 @@ impl AGainController {
}

impl IEditController for AGainController {
unsafe fn set_component_state(&self, state: *mut c_void) -> tresult {
unsafe fn set_component_state(&self, state: VstPtr<dyn IBStream>) -> tresult {
info!("Called: AGainController::set_component_state()");

if state.is_null() {
return kResultFalse;
}

let state = state as *mut *mut _;
let state: ComPtr<dyn IBStream> = ComPtr::new(state);

let mut num_bytes_read = 0;
let mut saved_gain = 0.0;
let mut saved_bypass = false;
let gain_ptr = &mut saved_gain as *mut f64 as *mut c_void;
let bypass_ptr = &mut saved_bypass as *mut bool as *mut c_void;

state.read(gain_ptr, mem::size_of::<f64>() as i32, &mut num_bytes_read);
state.read(
bypass_ptr,
mem::size_of::<bool>() as i32,
&mut num_bytes_read,
);

info!("saved_gain: {}", saved_gain);
info!("saved_bypass: {}", saved_bypass);

self.set_param_normalized(0, saved_gain);
self.set_param_normalized(1, if saved_bypass { 1.0 } else { 0.0 });

if let Some(state) = state.upgrade() {
let mut num_bytes_read = 0;
let mut saved_gain = 0.0;
let mut saved_bypass = false;
let gain_ptr = &mut saved_gain as *mut f64 as *mut c_void;
let bypass_ptr = &mut saved_bypass as *mut bool as *mut c_void;
state.read(gain_ptr, mem::size_of::<f64>() as i32, &mut num_bytes_read);
state.read(
bypass_ptr,
mem::size_of::<bool>() as i32,
&mut num_bytes_read,
);

info!("saved_gain: {}", saved_gain);
info!("saved_bypass: {}", saved_bypass);

self.set_param_normalized(0, saved_gain);
self.set_param_normalized(1, if saved_bypass { 1.0 } else { 0.0 });
}
kResultOk
}
unsafe fn set_state(&self, _state: *mut c_void) -> tresult {
unsafe fn set_state(&self, _state: VstPtr<dyn IBStream>) -> tresult {
info!("Called: AGainController::set_state()");

kResultOk
}
unsafe fn get_state(&self, _state: *mut c_void) -> tresult {
unsafe fn get_state(&self, _state: VstPtr<dyn IBStream>) -> tresult {
info!("Called: AGainController::get_state()");

kResultOk
Expand Down Expand Up @@ -678,10 +671,10 @@ impl IEditController for AGainController {
_ => kResultFalse,
}
}
unsafe fn set_component_handler(&self, handler: *mut c_void) -> tresult {
unsafe fn set_component_handler(&self, mut handler: VstPtr<dyn IComponentHandler>) -> tresult {
info!("Called: AGainController::set_component_handler()");

if self.component_handler.borrow().0 == handler {
if self.component_handler.borrow().0 == handler.as_raw_mut() as *mut _ {
return kResultTrue;
}

Expand All @@ -691,7 +684,7 @@ impl IEditController for AGainController {
component_handler.release();
}

self.component_handler.borrow_mut().0 = handler;
self.component_handler.borrow_mut().0 = handler.as_raw_mut() as *mut _;
if !self.component_handler.borrow().0.is_null() {
let component_handler = self.component_handler.borrow_mut().0 as *mut *mut _;
let component_handler: ComPtr<dyn IComponentHandler> = ComPtr::new(component_handler);
Expand Down
21 changes: 11 additions & 10 deletions examples/passthru.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@ use std::{
ptr::{copy_nonoverlapping, null_mut},
};
use vst3_com::{sys::GUID, IID};
use vst3_sys::utils::VstPtr;
use vst3_sys::{
base::{
kInvalidArgument, kResultFalse, kResultOk, tresult, FIDString, IPluginBase, IPluginFactory,
TBool,
kInvalidArgument, kResultFalse, kResultOk, tresult, FIDString, IBStream, IPluginBase,
IPluginFactory, TBool,
},
vst::{
AudioBusBuffers, BusDirection, BusDirections, BusFlags, BusInfo, IAudioPresentationLatency,
IAudioProcessor, IAutomationState, IComponent, IEditController, MediaTypes, ParameterInfo,
ProcessData, ProcessSetup, RoutingInfo, TChar,
IAudioProcessor, IAutomationState, IComponent, IComponentHandler, IEditController,
MediaTypes, ParameterInfo, ProcessData, ProcessSetup, RoutingInfo, TChar,
},
VST3,
};
Expand Down Expand Up @@ -60,15 +61,15 @@ impl PassthruPlugin {
pub struct Factory {}

impl IEditController for PassthruPlugin {
unsafe fn set_component_state(&self, _state: *mut c_void) -> tresult {
unsafe fn set_component_state(&self, _state: VstPtr<dyn IBStream>) -> tresult {
info!("set_component_state");
kResultOk
}
unsafe fn set_state(&self, _state: *mut c_void) -> tresult {
unsafe fn set_state(&self, _state: VstPtr<dyn IBStream>) -> tresult {
info!("set_state");
kResultOk
}
unsafe fn get_state(&self, _state: *mut c_void) -> tresult {
unsafe fn get_state(&self, _state: VstPtr<dyn IBStream>) -> tresult {
info!("get_state");
kResultOk
}
Expand Down Expand Up @@ -114,7 +115,7 @@ impl IEditController for PassthruPlugin {
info!("set_param_normalized");
kResultOk
}
unsafe fn set_component_handler(&self, _handler: *mut c_void) -> tresult {
unsafe fn set_component_handler(&self, _handler: VstPtr<dyn IComponentHandler>) -> tresult {
info!("set_component_handler");
kResultOk
}
Expand Down Expand Up @@ -261,11 +262,11 @@ impl IComponent for PassthruPlugin {
kResultOk
}

unsafe fn set_state(&self, _state: *mut c_void) -> tresult {
unsafe fn set_state(&self, _state: VstPtr<dyn IBStream>) -> tresult {
kResultOk
}

unsafe fn get_state(&self, _state: *mut c_void) -> tresult {
unsafe fn get_state(&self, _state: VstPtr<dyn IBStream>) -> tresult {
kResultOk
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! Utilities for consumers of the raw API
use vst3_com::{ComInterface, ComPtr};

/// A thin wrapper around a raw pointer to a vtable. Used in traits that return pointers to instances.
#[repr(transparent)]
#[derive(Copy, Clone, Debug)]
Expand All @@ -9,10 +8,14 @@ pub struct VstPtr<I: ComInterface + ?Sized> {
}

impl<I: ComInterface + ?Sized> VstPtr<I> {
pub fn as_raw_mut(&mut self) -> *mut *mut <I as ComInterface>::VTable {
self.inst
}
/// check if the underlying pointer is null
pub fn is_null(&self) -> bool {
self.inst.is_null()
}

/// Promote the pointer to a reference count, returns `None` if the pointer is null.
pub fn upgrade(&self) -> Option<ComPtr<I>> {
if self.inst.is_null() {
Expand Down
23 changes: 23 additions & 0 deletions src/vst/ivstaudioprocessor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,26 @@ pub trait IAudioPresentationLatency: IUnknown {
latency_samples: u32,
) -> tresult;
}

/// Flags used by [IProcessContextRequirements] to signal to the host what
/// data is required by the process context for your plugin. Required if you
/// plan to support > 3.7.0 hosts.
#[allow(non_snake_case)]
pub mod IProcessContextRequirementsFlags {
pub const kNeedSystemTime: u32 = 1;
pub const kNeedContinousTimeSamples: u32 = 1 << 1;
pub const kNeedProjectTimeMusic: u32 = 1 << 2;
pub const kNeedBarPositionMusic: u32 = 1 << 3;
pub const kNeedCycleMusic: u32 = 1 << 4;
pub const kNeedSamplesToNextClock: u32 = 1 << 5;
pub const kNeedTempo: u32 = 1 << 6;
pub const kNeedTimeSignature: u32 = 1 << 7;
pub const kNeedChord: u32 = 1 << 8;
pub const kNeedFrameRate: u32 = 1 << 9;
pub const kNeedTransportState: u32 = 1 << 10;
}

#[com_interface("2A654303-EF76-4E3D-95B5-FE83730EF6D0")]
pub trait IProcessContextRequirements: IUnknown {
unsafe fn get_process_context_requirements(&self) -> u32;
}
10 changes: 5 additions & 5 deletions src/vst/ivstcomponent.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::base::{tresult, FactoryFlags, IPluginBase, TBool};
use crate::base::{tresult, FactoryFlags, IBStream, IPluginBase, TBool};
use crate::utils::VstPtr;
use crate::vst::{BusDirection, IoMode, MediaType, String128};
use vst3_com::{c_void, com_interface, IID};

use vst3_com::{com_interface, IID};
pub const kDefaultFactoryFlags: i32 = FactoryFlags::kUnicode as i32;

pub enum MediaTypes {
Expand Down Expand Up @@ -76,6 +76,6 @@ pub trait IComponent: IPluginBase {
state: TBool,
) -> tresult;
unsafe fn set_active(&self, state: TBool) -> tresult;
unsafe fn set_state(&self, state: *mut c_void) -> tresult;
unsafe fn get_state(&self, state: *mut c_void) -> tresult;
unsafe fn set_state(&self, state: VstPtr<dyn IBStream>) -> tresult;
unsafe fn get_state(&self, state: VstPtr<dyn IBStream>) -> tresult;
}
29 changes: 24 additions & 5 deletions src/vst/ivsteditcontroller.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::base::{tresult, FIDString, IPluginBase, TBool};
use crate::base::{tchar, tresult, FIDString, IBStream, IPluginBase, TBool};
use crate::utils::VstPtr;
use crate::vst::{
BusDirection, CString, CtrlNumber, KnobMode, MediaType, ParamID, ParamValue, String128, TChar,
};
Expand Down Expand Up @@ -64,9 +65,9 @@ pub trait IComponentHandler: IUnknown {
/// Edit controller component interface.
#[com_interface("DCD7BBE3-7742-448D-A874-AACC979C759E")]
pub trait IEditController: IPluginBase {
unsafe fn set_component_state(&self, state: *mut c_void) -> tresult;
unsafe fn set_state(&self, state: *mut c_void) -> tresult;
unsafe fn get_state(&self, state: *mut c_void) -> tresult;
unsafe fn set_component_state(&self, state: VstPtr<dyn IBStream>) -> tresult;
unsafe fn set_state(&self, state: VstPtr<dyn IBStream>) -> tresult;
unsafe fn get_state(&self, state: VstPtr<dyn IBStream>) -> tresult;
unsafe fn get_parameter_count(&self) -> i32;
unsafe fn get_parameter_info(&self, param_index: i32, info: *mut ParameterInfo) -> tresult;
unsafe fn get_param_string_by_value(
Expand All @@ -85,7 +86,7 @@ pub trait IEditController: IPluginBase {
unsafe fn plain_param_to_normalized(&self, id: u32, plain_value: f64) -> f64;
unsafe fn get_param_normalized(&self, id: u32) -> f64;
unsafe fn set_param_normalized(&self, id: u32, value: f64) -> tresult;
unsafe fn set_component_handler(&self, handler: *mut c_void) -> tresult;
unsafe fn set_component_handler(&self, handler: VstPtr<dyn IComponentHandler>) -> tresult;
unsafe fn create_view(&self, name: FIDString) -> *mut c_void;
}

Expand Down Expand Up @@ -122,3 +123,21 @@ pub trait IEditControllerHostEditing: IUnknown {
unsafe fn begin_edit_from_host(&self, id: ParamID) -> tresult;
unsafe fn end_edit_from_host(&self, id: ParamID) -> tresult;
}

#[allow(non_snake_case)]
pub mod ProgressType {
pub const AsyncStateRestoration: u32 = 0;
pub const UIBackgroundTask: u32 = 1;
}

#[com_interface("00C9DC5B-9D90-4254-91A3-88C8B4E91B69")]
pub trait IProgress: IUnknown {
unsafe fn start(
&self,
progress_type: u32,
optional_description: *const tchar,
out_id: *mut u64,
) -> i32; // fucking _why_
unsafe fn update(&self, id: u64, value: f64);
unsafe fn finish(&self, id: u64);
}
26 changes: 26 additions & 0 deletions src/vst/ivstparameterfunctionname.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use crate::base::{tresult, FIDString};
use crate::vst::{ParamID, UnitID};
use vst3_com::com_interface;
use vst3_com::interfaces::iunknown::IUnknown;

#[allow(non_snake_case)]
pub mod FunctionNameType {
pub const kStringStereoTRS: &[u8] = b"Trl Trr\0";
pub const kCompGainReduction: &[u8] = b"Comp:GainReduction\0";
pub const kCompGainReductionMax: &[u8] = b"Comp:GainReductionMax\0";
pub const kCompGainReductionPeakHold: &[u8] = b"Comp:GainReductionPeakHold\0";
pub const kCompResetGainReductionMax: &[u8] = b"Comp:ResetGainReductionMax\0";
pub const kLowLatencyMode: &[u8] = b"LowLatencyMode\0";
pub const kRandomize: &[u8] = b"Randomize\0";
pub const kWetDryMix: &[u8] = b"WetDryMix\0";
}

#[com_interface("6D21E1DC-9119-9D4B-A2A0-2FEF6C1AE55C")]
pub trait IParameterFunctionName: IUnknown {
unsafe fn get_parameter_id_from_function_name(
&self,
unit_id: UnitID,
function_name: FIDString,
parameter_id: ParamID,
) -> tresult;
}
3 changes: 3 additions & 0 deletions src/vst/ivstprocesscontext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ pub struct ProcessContext {
pub bar_position_music: f64,
pub cycle_start_music: f64,
pub cycle_end_music: f64,
pub tempo: f64,
pub time_sig_num: i32,
pub time_sig_den: i32,
pub chord: Chord,
pub smpte_offset_subframes: i32,
pub frame_rate: FrameRate,
Expand Down
3 changes: 2 additions & 1 deletion src/vst/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ mod ivstmidicontroller;
mod ivstmidilearn;
mod ivstnoteexpression;
mod ivstparameterchanges;
mod ivstparameterfunctionname;
mod ivstphysicalui;
mod ivstpluginteracesupport;
mod ivstplugview;
Expand All @@ -36,6 +37,7 @@ pub use ivstmidicontroller::*;
pub use ivstmidilearn::*;
pub use ivstnoteexpression::*;
pub use ivstparameterchanges::*;
pub use ivstparameterfunctionname::*;
pub use ivstphysicalui::*;
pub use ivstpluginteracesupport::*;
pub use ivstplugview::*;
Expand All @@ -45,4 +47,3 @@ pub use ivstrepresentation::*;
pub use ivstunits::*;
pub use vstspeaker::*;
pub use vsttypes::*;
// test/itest vstspeaker.h,
4 changes: 2 additions & 2 deletions src/vst/vsttypes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub type KnobMode = i32;

pub const kNoParamId: ParamID = 0xFFFF_FFFF;
pub const kVstVersionMajor: i32 = 3;
pub const kVstVersionMinor: i32 = 6;
pub const kVstVersionSub: i32 = 13;
pub const kVstVersionMinor: i32 = 7;
pub const kVstVersionSub: i32 = 0;
pub const VST_VERSION: i32 = (kVstVersionMajor << 16) | (kVstVersionMinor << 8) | kVstVersionSub;
pub const kVstVersionString: CString = b"VST 3.6.13\0".as_ptr() as *const _;