add base-pan decoding
left channel is base signal, right channel is stereo balance modulatormain
parent
a70a47d668
commit
1919b0a166
|
@ -0,0 +1,9 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = false
|
||||
insert_final_newline = true
|
File diff suppressed because it is too large
Load Diff
|
@ -14,6 +14,7 @@ crate-type = ["cdylib"]
|
|||
|
||||
[dependencies]
|
||||
nih_plug = { git = "https://github.com/robbert-vdh/nih-plug.git", features = ["assert_process_allocs"] }
|
||||
nih_plug_vizia = { git = "https://github.com/robbert-vdh/nih-plug.git" }
|
||||
|
||||
[profile.release]
|
||||
lto = "thin"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# charlotte's mid side
|
||||
|
||||
simple mid side decoder. left channel -> mid, right channel -> side (positive values pan right, negative values pan left)
|
||||
multimodal stereo signal decoder
|
||||
|
||||
## Building
|
||||
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use nih_plug::prelude::*;
|
||||
|
||||
use nih_plug_vizia::vizia::prelude::*;
|
||||
use nih_plug_vizia::widgets::{ParamSlider, ResizeHandle};
|
||||
use nih_plug_vizia::{create_vizia_editor, ViziaState};
|
||||
|
||||
use crate::MidSideParams;
|
||||
|
||||
#[derive(Lens)]
|
||||
struct Data {
|
||||
params: Arc<MidSideParams>,
|
||||
}
|
||||
|
||||
impl Model for Data {}
|
||||
|
||||
pub fn default_state() -> Arc<ViziaState> {
|
||||
ViziaState::new(|| (320, 100))
|
||||
}
|
||||
|
||||
pub fn create(state: Arc<ViziaState>, params: Arc<MidSideParams>) -> Option<Box<dyn Editor>> {
|
||||
create_vizia_editor(
|
||||
state,
|
||||
nih_plug_vizia::ViziaTheming::Builtin,
|
||||
move |cx, _| {
|
||||
nih_plug_vizia::assets::register_noto_sans_light(cx);
|
||||
nih_plug_vizia::assets::register_noto_sans_thin(cx);
|
||||
|
||||
Data {
|
||||
params: params.clone(),
|
||||
}
|
||||
.build(cx);
|
||||
|
||||
ResizeHandle::new(cx);
|
||||
VStack::new(cx, |cx| {
|
||||
ParamSlider::new(cx, Data::params, |p| &p.mode);
|
||||
});
|
||||
},
|
||||
)
|
||||
}
|
61
src/lib.rs
61
src/lib.rs
|
@ -1,10 +1,10 @@
|
|||
use nih_plug::prelude::*;
|
||||
use nih_plug_vizia::ViziaState;
|
||||
use std::sync::Arc;
|
||||
|
||||
fn decode_mid_side(channel_0: &mut [f32], channel_1: &mut [f32]) {
|
||||
// positive sides -> pan right
|
||||
// negative sides -> pan left
|
||||
mod editor;
|
||||
|
||||
fn decode_mid_side(channel_0: &mut [f32], channel_1: &mut [f32]) {
|
||||
assert_eq!(channel_0.len(), channel_1.len());
|
||||
|
||||
for sample_idx in 0..channel_0.len() {
|
||||
|
@ -19,10 +19,50 @@ fn decode_mid_side(channel_0: &mut [f32], channel_1: &mut [f32]) {
|
|||
}
|
||||
}
|
||||
|
||||
fn decode_signal_balance(channel_0: &mut [f32], channel_1: &mut [f32]) {
|
||||
// positive balance -> pan right
|
||||
// negative balance -> pan left
|
||||
|
||||
assert_eq!(channel_0.len(), channel_1.len());
|
||||
|
||||
for sample_idx in 0..channel_0.len() {
|
||||
let sig = channel_0[sample_idx];
|
||||
let balance = channel_1[sample_idx];
|
||||
|
||||
let left = sig * (0.5 * -balance + 1.0);
|
||||
let right = sig * (0.5 * balance + 1.0);
|
||||
|
||||
channel_0[sample_idx] = left;
|
||||
channel_1[sample_idx] = right;
|
||||
}
|
||||
}
|
||||
|
||||
// time to wire up nih-plug. all of this is boilerplate
|
||||
|
||||
#[derive(Enum, PartialEq, Eq)]
|
||||
pub enum MidSideMode {
|
||||
#[id = "conventional"]
|
||||
Conventional,
|
||||
#[id = "balance"]
|
||||
PanAmount,
|
||||
}
|
||||
|
||||
#[derive(Params)]
|
||||
struct MidSideParams {}
|
||||
pub struct MidSideParams {
|
||||
#[id = "mode"]
|
||||
mode: EnumParam<MidSideMode>,
|
||||
#[persist = "editor-state"]
|
||||
editor_state: Arc<ViziaState>,
|
||||
}
|
||||
|
||||
impl Default for MidSideParams {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
mode: EnumParam::new("Mode", MidSideMode::Conventional),
|
||||
editor_state: editor::default_state(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct MidSide {
|
||||
params: Arc<MidSideParams>,
|
||||
|
@ -31,7 +71,7 @@ struct MidSide {
|
|||
impl Default for MidSide {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
params: Arc::new(MidSideParams {}),
|
||||
params: Arc::new(MidSideParams::default()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,13 +119,18 @@ impl Plugin for MidSide {
|
|||
) -> ProcessStatus {
|
||||
assert_eq!(buffer.channels(), 2);
|
||||
|
||||
let mode = self.params.mode.value();
|
||||
|
||||
for (_block_idx, block) in buffer.iter_blocks(128) {
|
||||
let mut block_channels = block.into_iter();
|
||||
|
||||
let channel_0 = block_channels.next().unwrap();
|
||||
let channel_1 = block_channels.next().unwrap();
|
||||
|
||||
decode_mid_side(channel_0, channel_1);
|
||||
match mode {
|
||||
MidSideMode::Conventional => decode_mid_side(channel_0, channel_1),
|
||||
MidSideMode::PanAmount => decode_signal_balance(channel_0, channel_1),
|
||||
}
|
||||
}
|
||||
|
||||
ProcessStatus::Normal
|
||||
|
@ -94,6 +139,10 @@ impl Plugin for MidSide {
|
|||
fn params(&self) -> Arc<dyn Params> {
|
||||
self.params.clone()
|
||||
}
|
||||
|
||||
fn editor(&mut self, _async_executor: AsyncExecutor<Self>) -> Option<Box<dyn Editor>> {
|
||||
editor::create(self.params.editor_state.clone(), self.params.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl Vst3Plugin for MidSide {
|
||||
|
|
Loading…
Reference in New Issue