use crate::buffer::{AuxiliaryBuffers, Buffer};
use crate::error::{PluginError, PluginResult};
use crate::midi::{
KeyswitchInfo, Midi2Controller, MidiBuffer, MidiEvent, MpeInputDeviceSettings,
NoteExpressionTypeInfo, PhysicalUIMap,
};
use crate::midi_cc_config::MidiCcConfig;
use crate::parameter_groups::ParameterGroups;
use crate::parameter_store::ParameterStore;
use crate::parameter_types::Parameters;
use crate::process_context::ProcessContext;
pub trait HasParameters: Send + 'static {
type Parameters: ParameterStore + ParameterGroups + crate::parameter_types::Parameters + Default;
fn parameters(&self) -> &Self::Parameters;
fn parameters_mut(&mut self) -> &mut Self::Parameters;
fn set_parameters(&mut self, params: Self::Parameters);
}
#[derive(Clone, Debug)]
pub struct HostSetup {
pub sample_rate: f64,
pub max_buffer_size: usize,
pub layout: BusLayout,
pub process_mode: ProcessMode,
}
impl HostSetup {
pub fn new(sample_rate: f64, max_buffer_size: usize, layout: BusLayout, process_mode: ProcessMode) -> Self {
Self {
sample_rate,
max_buffer_size,
layout,
process_mode,
}
}
}
pub trait PluginSetup: Clone + Send + 'static {
fn extract(host: &HostSetup) -> Self;
}
impl PluginSetup for () {
fn extract(_: &HostSetup) -> Self {}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct SampleRate(pub f64);
impl SampleRate {
#[inline]
pub fn hz(&self) -> f64 {
self.0
}
}
impl PluginSetup for SampleRate {
fn extract(host: &HostSetup) -> Self {
SampleRate(host.sample_rate)
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct MaxBufferSize(pub usize);
impl PluginSetup for MaxBufferSize {
fn extract(host: &HostSetup) -> Self {
MaxBufferSize(host.max_buffer_size)
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct MainInputChannels(pub u32);
impl PluginSetup for MainInputChannels {
fn extract(host: &HostSetup) -> Self {
MainInputChannels(host.layout.main_input_channels)
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct MainOutputChannels(pub u32);
impl PluginSetup for MainOutputChannels {
fn extract(host: &HostSetup) -> Self {
MainOutputChannels(host.layout.main_output_channels)
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct AuxInputCount(pub usize);
impl PluginSetup for AuxInputCount {
fn extract(host: &HostSetup) -> Self {
AuxInputCount(host.layout.aux_input_count)
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct AuxOutputCount(pub usize);
impl PluginSetup for AuxOutputCount {
fn extract(host: &HostSetup) -> Self {
AuxOutputCount(host.layout.aux_output_count)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub enum ProcessMode {
#[default]
Realtime,
Offline,
Prefetch,
}
impl PluginSetup for ProcessMode {
fn extract(host: &HostSetup) -> Self {
host.process_mode
}
}
impl<A, B> PluginSetup for (A, B)
where
A: PluginSetup,
B: PluginSetup,
{
fn extract(host: &HostSetup) -> Self {
(A::extract(host), B::extract(host))
}
}
impl<A, B, C> PluginSetup for (A, B, C)
where
A: PluginSetup,
B: PluginSetup,
C: PluginSetup,
{
fn extract(host: &HostSetup) -> Self {
(A::extract(host), B::extract(host), C::extract(host))
}
}
impl<A, B, C, D> PluginSetup for (A, B, C, D)
where
A: PluginSetup,
B: PluginSetup,
C: PluginSetup,
D: PluginSetup,
{
fn extract(host: &HostSetup) -> Self {
(A::extract(host), B::extract(host), C::extract(host), D::extract(host))
}
}
impl<A, B, C, D, E> PluginSetup for (A, B, C, D, E)
where
A: PluginSetup,
B: PluginSetup,
C: PluginSetup,
D: PluginSetup,
E: PluginSetup,
{
fn extract(host: &HostSetup) -> Self {
(A::extract(host), B::extract(host), C::extract(host), D::extract(host), E::extract(host))
}
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct BusLayout {
pub main_input_channels: u32,
pub main_output_channels: u32,
pub aux_input_count: usize,
pub aux_output_count: usize,
}
impl BusLayout {
pub const fn stereo() -> Self {
Self {
main_input_channels: 2,
main_output_channels: 2,
aux_input_count: 0,
aux_output_count: 0,
}
}
pub fn from_plugin<P: Descriptor>(plugin: &P) -> Self {
Self {
main_input_channels: plugin
.input_bus_info(0)
.map(|b| b.channel_count)
.unwrap_or(2),
main_output_channels: plugin
.output_bus_info(0)
.map(|b| b.channel_count)
.unwrap_or(2),
aux_input_count: plugin.input_bus_count().saturating_sub(1),
aux_output_count: plugin.output_bus_count().saturating_sub(1),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum BusType {
#[default]
Main,
Aux,
}
#[derive(Debug, Clone)]
pub struct BusInfo {
pub name: &'static str,
pub bus_type: BusType,
pub channel_count: u32,
pub is_default_active: bool,
}
impl Default for BusInfo {
fn default() -> Self {
Self {
name: "Main",
bus_type: BusType::Main,
channel_count: 2,
is_default_active: true,
}
}
}
impl BusInfo {
pub const fn stereo(name: &'static str) -> Self {
Self {
name,
bus_type: BusType::Main,
channel_count: 2,
is_default_active: true,
}
}
pub const fn mono(name: &'static str) -> Self {
Self {
name,
bus_type: BusType::Main,
channel_count: 1,
is_default_active: true,
}
}
pub const fn aux(name: &'static str, channel_count: u32) -> Self {
Self {
name,
bus_type: BusType::Aux,
channel_count,
is_default_active: false,
}
}
}
pub trait Processor: HasParameters {
type Descriptor: Descriptor<Processor = Self, Parameters = Self::Parameters>;
fn process(&mut self, buffer: &mut Buffer, aux: &mut AuxiliaryBuffers, context: &ProcessContext);
fn unprepare(mut self) -> Self::Descriptor
where
Self: Sized,
{
let params = std::mem::take(self.parameters_mut());
let mut definition = Self::Descriptor::default();
definition.set_parameters(params);
definition
}
fn set_active(&mut self, _active: bool) {}
fn tail_samples(&self) -> u32 {
0
}
fn latency_samples(&self) -> u32 {
0
}
fn bypass_ramp_samples(&self) -> u32 {
64
}
fn supports_double_precision(&self) -> bool {
false
}
fn process_f64(
&mut self,
buffer: &mut Buffer<f64>,
_aux: &mut AuxiliaryBuffers<f64>,
context: &ProcessContext,
) {
let num_samples = buffer.num_samples();
let num_input_channels = buffer.num_input_channels();
let num_output_channels = buffer.num_output_channels();
let input_f32: Vec<Vec<f32>> = (0..num_input_channels)
.map(|ch| buffer.input(ch).iter().map(|&s| s as f32).collect())
.collect();
let mut output_f32: Vec<Vec<f32>> = (0..num_output_channels)
.map(|_| vec![0.0f32; num_samples])
.collect();
let input_slices: Vec<&[f32]> = input_f32.iter().map(|v| v.as_slice()).collect();
let output_slices: Vec<&mut [f32]> = output_f32
.iter_mut()
.map(|v| v.as_mut_slice())
.collect();
let mut buffer_f32 = Buffer::new(input_slices, output_slices, num_samples);
let mut aux_f32: AuxiliaryBuffers<f32> = AuxiliaryBuffers::empty();
self.process(&mut buffer_f32, &mut aux_f32, context);
for (ch, output_samples) in output_f32.iter().enumerate().take(num_output_channels) {
let output_ch = buffer.output(ch);
for (i, sample) in output_samples.iter().enumerate() {
output_ch[i] = *sample as f64;
}
}
}
fn save_state(&self) -> PluginResult<Vec<u8>> {
Ok(self.parameters().save_state())
}
fn load_state(&mut self, data: &[u8]) -> PluginResult<()> {
self.parameters_mut()
.load_state(data)
.map_err(PluginError::StateError)
}
fn process_midi(&mut self, input: &[MidiEvent], output: &mut MidiBuffer) {
for event in input {
output.push(event.clone());
}
}
fn wants_midi(&self) -> bool {
false
}
}
pub trait Descriptor: HasParameters + Default {
type Setup: PluginSetup;
type Processor: Processor<Descriptor = Self, Parameters = Self::Parameters>;
fn prepare(self, setup: Self::Setup) -> Self::Processor;
fn input_bus_count(&self) -> usize {
1
}
fn output_bus_count(&self) -> usize {
1
}
fn input_bus_info(&self, index: usize) -> Option<BusInfo> {
if index == 0 {
Some(BusInfo::stereo("Input"))
} else {
None
}
}
fn output_bus_info(&self, index: usize) -> Option<BusInfo> {
if index == 0 {
Some(BusInfo::stereo("Output"))
} else {
None
}
}
fn wants_midi(&self) -> bool {
false
}
fn midi_cc_to_parameter(&self, bus_index: i32, channel: i16, cc: u8) -> Option<u32> {
let _ = (bus_index, channel, cc);
None
}
fn midi_cc_config(&self) -> Option<MidiCcConfig> {
None
}
fn on_midi_learn(&mut self, bus_index: i32, channel: i16, cc: u8) -> bool {
let _ = (bus_index, channel, cc);
false
}
fn midi1_assignments(&self) -> &[Midi1Assignment] {
&[]
}
fn midi2_assignments(&self) -> &[Midi2Assignment] {
&[]
}
fn on_midi1_learn(&mut self, bus_index: i32, channel: u8, cc: u8) -> bool {
let _ = (bus_index, channel, cc);
false
}
fn on_midi2_learn(&mut self, bus_index: i32, channel: u8, controller: Midi2Controller) -> bool {
let _ = (bus_index, channel, controller);
false
}
fn note_expression_count(&self, bus_index: i32, channel: i16) -> usize {
let _ = (bus_index, channel);
0
}
fn note_expression_info(
&self,
bus_index: i32,
channel: i16,
index: usize,
) -> Option<NoteExpressionTypeInfo> {
let _ = (bus_index, channel, index);
None
}
fn note_expression_value_to_string(
&self,
bus_index: i32,
channel: i16,
type_id: u32,
value: f64,
) -> String {
let _ = (bus_index, channel, type_id);
format!("{:.1}%", value * 100.0)
}
fn note_expression_string_to_value(
&self,
bus_index: i32,
channel: i16,
type_id: u32,
string: &str,
) -> Option<f64> {
let _ = (bus_index, channel, type_id, string);
None
}
fn keyswitch_count(&self, bus_index: i32, channel: i16) -> usize {
let _ = (bus_index, channel);
0
}
fn keyswitch_info(&self, bus_index: i32, channel: i16, index: usize) -> Option<KeyswitchInfo> {
let _ = (bus_index, channel, index);
None
}
fn physical_ui_mappings(&self, bus_index: i32, channel: i16) -> &[PhysicalUIMap] {
let _ = (bus_index, channel);
&[]
}
fn enable_mpe_input_processing(&mut self, enabled: bool) -> bool {
let _ = enabled;
true
}
fn set_mpe_input_device_settings(&mut self, settings: MpeInputDeviceSettings) -> bool {
let _ = settings;
true
}
}
#[derive(Debug, Clone, Copy)]
pub struct MidiControllerAssignment {
pub parameter_id: u32,
pub bus_index: i32,
pub channel: u8,
}
#[derive(Debug, Clone, Copy)]
pub struct Midi1Assignment {
pub assignment: MidiControllerAssignment,
pub controller: u8,
}
impl Midi1Assignment {
pub const fn new(parameter_id: u32, bus_index: i32, channel: u8, controller: u8) -> Self {
Self {
assignment: MidiControllerAssignment {
parameter_id,
bus_index,
channel,
},
controller,
}
}
pub const fn simple(parameter_id: u32, controller: u8) -> Self {
Self::new(parameter_id, 0, 0, controller)
}
}
#[derive(Debug, Clone, Copy)]
pub struct Midi2Assignment {
pub assignment: MidiControllerAssignment,
pub controller: Midi2Controller,
}
impl Midi2Assignment {
pub const fn new(
parameter_id: u32,
bus_index: i32,
channel: u8,
controller: Midi2Controller,
) -> Self {
Self {
assignment: MidiControllerAssignment {
parameter_id,
bus_index,
channel,
},
controller,
}
}
pub const fn simple(parameter_id: u32, controller: Midi2Controller) -> Self {
Self::new(parameter_id, 0, 0, controller)
}
}