feat(weld): add sidechain test build
Weld will phase-align a bass layer to another layer it hears through the sidechain. This first build only checks that FL Studio delivers the sidechain to a CLAP aux port: it passes the main layer through unchanged, meters the sidechain and offers Layer/Sum/Sum dry listening. No latency.
This commit is contained in:
1 parent
b3ebe4d952
commit
e3286f9094
21 files changed
+3471
-9
No files matched your search
@@ -0,0 +1,104 @@
|
||||
use nih_plug::prelude::*;
|
||||
use nih_plug_egui::EguiState;
|
||||
use std::sync::Arc;
|
||||
use weld_core::{Listen, Settings};
|
||||
|
||||
#[derive(Enum, Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub enum ListenParam {
|
||||
#[id = "layer"]
|
||||
Layer,
|
||||
#[id = "sum"]
|
||||
Sum,
|
||||
#[id = "sum-dry"]
|
||||
#[name = "Sum dry"]
|
||||
SumDry,
|
||||
}
|
||||
/// Continuous controls, in the order of the gesture slots.
|
||||
const FLOATS: usize = 1;
|
||||
|
||||
#[derive(Params)]
|
||||
pub struct WeldParams {
|
||||
#[persist = "editor"]
|
||||
pub editor: Arc<EguiState>,
|
||||
#[id = "listen"]
|
||||
pub listen: EnumParam<ListenParam>,
|
||||
#[id = "output"]
|
||||
pub output: FloatParam,
|
||||
#[id = "bypass"]
|
||||
pub bypass: BoolParam,
|
||||
}
|
||||
impl Default for WeldParams {
|
||||
fn default() -> Self {
|
||||
let d = Settings::default();
|
||||
Self {
|
||||
editor: EguiState::from_size(weld_ui::WIDTH, weld_ui::HEIGHT),
|
||||
listen: EnumParam::new("Listen", ListenParam::Layer),
|
||||
output: FloatParam::new(
|
||||
"Output",
|
||||
d.output,
|
||||
FloatRange::Linear {
|
||||
min: -12.,
|
||||
max: 12.,
|
||||
},
|
||||
)
|
||||
.with_unit(" dB"),
|
||||
bypass: BoolParam::new("Bypass", false).make_bypass(),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl WeldParams {
|
||||
pub fn settings(&self) -> Settings {
|
||||
Settings {
|
||||
listen: match self.listen.value() {
|
||||
ListenParam::Layer => Listen::Layer,
|
||||
ListenParam::Sum => Listen::Sum,
|
||||
ListenParam::SumDry => Listen::SumDry,
|
||||
},
|
||||
output: self.output.value(),
|
||||
bypass: self.bypass.value(),
|
||||
}
|
||||
}
|
||||
fn floats(&self) -> [&FloatParam; FLOATS] {
|
||||
[&self.output]
|
||||
}
|
||||
/// Pushes every changed editor value to the host. Continuous controls hold one gesture
|
||||
/// while the pointer is down; switches are set in a single gesture.
|
||||
pub fn apply(
|
||||
&self,
|
||||
setter: &ParamSetter,
|
||||
old: &Settings,
|
||||
new: &Settings,
|
||||
dragging: bool,
|
||||
open: &mut [bool; FLOATS],
|
||||
) {
|
||||
let values = [(old.output, new.output)];
|
||||
for (i, (p, (a, b))) in self.floats().into_iter().zip(values).enumerate() {
|
||||
if a != b {
|
||||
if !open[i] {
|
||||
open[i] = true;
|
||||
setter.begin_set_parameter(p);
|
||||
}
|
||||
setter.set_parameter(p, b);
|
||||
}
|
||||
if !dragging && open[i] {
|
||||
setter.end_set_parameter(p);
|
||||
open[i] = false;
|
||||
}
|
||||
}
|
||||
if new.bypass != old.bypass {
|
||||
setter.begin_set_parameter(&self.bypass);
|
||||
setter.set_parameter(&self.bypass, new.bypass);
|
||||
setter.end_set_parameter(&self.bypass);
|
||||
}
|
||||
if new.listen != old.listen {
|
||||
let v = match new.listen {
|
||||
Listen::Layer => ListenParam::Layer,
|
||||
Listen::Sum => ListenParam::Sum,
|
||||
Listen::SumDry => ListenParam::SumDry,
|
||||
};
|
||||
setter.begin_set_parameter(&self.listen);
|
||||
setter.set_parameter(&self.listen, v);
|
||||
setter.end_set_parameter(&self.listen);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user