From 05ae8fd428a5144d100c485edb71b5c9356095b3 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Tue, 25 Jan 2022 23:02:15 +0100 Subject: [PATCH] Add a very basic gain plugin with some todos --- plugins/gain/src/lib.rs | 110 +++++++++++++++++++++++++++++++--------- 1 file changed, 86 insertions(+), 24 deletions(-) diff --git a/plugins/gain/src/lib.rs b/plugins/gain/src/lib.rs index 3c0b7327..2a501632 100644 --- a/plugins/gain/src/lib.rs +++ b/plugins/gain/src/lib.rs @@ -1,33 +1,95 @@ -use nih_plug::params::{FloatParam, IntParam, Params, Range}; +use nih_plug::{ + params::{FloatParam, Params, Range}, + plugin::{BufferConfig, BusConfig, Plugin}, +}; use nih_plug_derive::Params; +use std::pin::Pin; -#[derive(Params)] -struct FooParams { - #[id("pain")] - pub pain: FloatParam, - #[id("pain_stages")] - pub pain_stages: IntParam, - - #[id("identifiers_are_stable")] - pub but_field_names_can_change: FloatParam, +struct Gain { + params: Pin>, } -impl Default for FooParams { +#[derive(Params)] +struct GainParams { + #[id("gain")] + pub gain: FloatParam, +} + +impl Default for Gain { fn default() -> Self { Self { - pain: FloatParam { - value: 69.0, - range: Range::Linear { - min: -420.0, - max: 420.0, - }, - name: "Pain", - unit: " Hertz", - value_to_string: None, - string_to_value: None, - }, - pain_stages: todo!(), - but_field_names_can_change: todo!(), + params: Pin::new(Box::default()), + } + } +} + +impl Default for GainParams { + fn default() -> Self { + Self { + gain: FloatParam { + value: 0.00, + range: Range::Linear { + min: -30.0, + max: 300.0, + }, + name: "Gain", + unit: " dB", + value_to_string: None, + string_to_value: None, + }, + } + } +} + +impl Plugin for Gain { + const DEFAULT_NUM_INPUTS: u32 = 2; + const DEFAULT_NUM_OUTPUTS: u32 = 2; + + fn params(&self) -> Pin<&dyn Params> { + todo!() + } + + fn accepts_bus_config(&self, config: &BusConfig) -> bool { + // This works with any symmetrical IO layout + config.num_input_channels == config.num_output_channels && config.num_input_channels > 0 + } + + fn initialize(&mut self, _bus_config: &BusConfig, _buffer_config: &BufferConfig) -> bool { + // This plugin doesn't need any special initialization, but if you need to do anything + // expensive then this would be the place. State is kept around while when the host + // reconfigures the plugin. + true + } + + fn process(&mut self, samples: &mut [&mut [f32]]) { + if samples.is_empty() { + return; + } + + // TODO: The wrapper should set FTZ if not yet enabled, mention ths in the process fuctnion + // TODO: Move this iterator to an adapter + let num_channels = samples.len(); + let num_samples = samples[0].len(); + for channel in &samples[1..] { + if channel.len() != num_samples { + // TODO: Debug assert + eprintln!("Mismatched channel lengths, aborting"); + return; + } + } + + for sample_idx in 0..num_samples { + for channel_idx in 0..num_channels { + let sample = unsafe { + samples + .get_unchecked_mut(channel_idx) + .get_unchecked_mut(sample_idx) + }; + + // TODO: Smoothing + // TODO: Gain to decibel function in a separate module, add a minus infinity check when I do + *sample *= 10.0f32.powf(self.params.gain.value * 0.05); + } } } }