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]
|
[dependencies]
|
||||||
nih_plug = { git = "https://github.com/robbert-vdh/nih-plug.git", features = ["assert_process_allocs"] }
|
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]
|
[profile.release]
|
||||||
lto = "thin"
|
lto = "thin"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# charlotte's mid side
|
# 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
|
## 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::prelude::*;
|
||||||
|
use nih_plug_vizia::ViziaState;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
fn decode_mid_side(channel_0: &mut [f32], channel_1: &mut [f32]) {
|
mod editor;
|
||||||
// positive sides -> pan right
|
|
||||||
// negative sides -> pan left
|
|
||||||
|
|
||||||
|
fn decode_mid_side(channel_0: &mut [f32], channel_1: &mut [f32]) {
|
||||||
assert_eq!(channel_0.len(), channel_1.len());
|
assert_eq!(channel_0.len(), channel_1.len());
|
||||||
|
|
||||||
for sample_idx in 0..channel_0.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
|
// 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)]
|
#[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 {
|
struct MidSide {
|
||||||
params: Arc<MidSideParams>,
|
params: Arc<MidSideParams>,
|
||||||
|
@ -31,7 +71,7 @@ struct MidSide {
|
||||||
impl Default for MidSide {
|
impl Default for MidSide {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
params: Arc::new(MidSideParams {}),
|
params: Arc::new(MidSideParams::default()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,13 +119,18 @@ impl Plugin for MidSide {
|
||||||
) -> ProcessStatus {
|
) -> ProcessStatus {
|
||||||
assert_eq!(buffer.channels(), 2);
|
assert_eq!(buffer.channels(), 2);
|
||||||
|
|
||||||
|
let mode = self.params.mode.value();
|
||||||
|
|
||||||
for (_block_idx, block) in buffer.iter_blocks(128) {
|
for (_block_idx, block) in buffer.iter_blocks(128) {
|
||||||
let mut block_channels = block.into_iter();
|
let mut block_channels = block.into_iter();
|
||||||
|
|
||||||
let channel_0 = block_channels.next().unwrap();
|
let channel_0 = block_channels.next().unwrap();
|
||||||
let channel_1 = 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
|
ProcessStatus::Normal
|
||||||
|
@ -94,6 +139,10 @@ impl Plugin for MidSide {
|
||||||
fn params(&self) -> Arc<dyn Params> {
|
fn params(&self) -> Arc<dyn Params> {
|
||||||
self.params.clone()
|
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 {
|
impl Vst3Plugin for MidSide {
|
||||||
|
|
Loading…
Reference in New Issue