use crate::graph::{
ParamDescriptor, ParamFlags, ParamUnit, ProcessContext, Processor, ProcessorInfo, Sig,
};
pub struct Gain {
pub level: f32,
pub pan: f32,
}
impl Gain {
pub fn new(level: f32) -> Self {
Self { level, pan: 0.0 }
}
pub fn with_pan(level: f32, pan: f32) -> Self {
Self { level, pan }
}
}
impl Processor for Gain {
fn info(&self) -> ProcessorInfo {
ProcessorInfo {
name: "gain",
sig: Sig {
inputs: 1,
outputs: 2,
},
description: "Mono to stereo with level and pan",
}
}
fn process(&mut self, ctx: &mut ProcessContext) {
let angle = (self.pan + 1.0) * 0.25 * std::f32::consts::PI;
let gain_l = self.level * angle.cos();
let gain_r = self.level * angle.sin();
for i in 0..ctx.frames {
let s = ctx.inputs[0][i];
ctx.outputs[0][i] = s * gain_l;
ctx.outputs[1][i] = s * gain_r;
}
}
fn reset(&mut self) {}
fn params(&self) -> Vec<ParamDescriptor> {
vec![
ParamDescriptor {
id: 0,
name: "Level",
min: 0.0,
max: 2.0,
default: 1.0,
unit: ParamUnit::Linear,
flags: ParamFlags::NONE,
step: 0.05,
group: None,
help: "",
},
ParamDescriptor {
id: 1,
name: "Pan",
min: -1.0,
max: 1.0,
default: 0.0,
unit: ParamUnit::Linear,
flags: ParamFlags::BIPOLAR,
step: 0.05,
group: None,
help: "",
},
]
}
fn get_param(&self, id: u32) -> f64 {
match id {
0 => self.level as f64,
1 => self.pan as f64,
_ => 0.0,
}
}
fn set_param(&mut self, id: u32, value: f64) {
match id {
0 => self.level = value.clamp(0.0, 2.0) as f32,
1 => self.pan = value.clamp(-1.0, 1.0) as f32,
_ => {}
}
}
}
pub struct StereoGain {
pub level: f32,
}
impl StereoGain {
pub fn new(level: f32) -> Self {
Self { level }
}
}
impl Processor for StereoGain {
fn info(&self) -> ProcessorInfo {
ProcessorInfo {
name: "stereo_gain",
sig: Sig::STEREO,
description: "Stereo level control",
}
}
fn process(&mut self, ctx: &mut ProcessContext) {
let lvl = self.level;
for i in 0..ctx.frames {
ctx.outputs[0][i] = ctx.inputs[0][i] * lvl;
ctx.outputs[1][i] = ctx.inputs[1][i] * lvl;
}
}
fn reset(&mut self) {}
fn params(&self) -> Vec<ParamDescriptor> {
vec![ParamDescriptor {
id: 0,
name: "Level",
min: 0.0,
max: 2.0,
default: 1.0,
unit: ParamUnit::Linear,
flags: ParamFlags::NONE,
step: 0.05,
group: None,
help: "",
}]
}
fn get_param(&self, id: u32) -> f64 {
match id {
0 => self.level as f64,
_ => 0.0,
}
}
fn set_param(&mut self, id: u32, value: f64) {
match id {
0 => self.level = value.clamp(0.0, 2.0) as f32,
_ => {}
}
}
}
pub struct StereoPan {
pub pan: f32,
}
impl StereoPan {
pub fn new(pan: f32) -> Self {
Self { pan }
}
}
impl Processor for StereoPan {
fn info(&self) -> ProcessorInfo {
ProcessorInfo {
name: "stereo_pan",
sig: Sig::STEREO,
description: "Stereo panning control",
}
}
fn process(&mut self, ctx: &mut ProcessContext) {
let angle = (self.pan + 1.0) * 0.25 * std::f32::consts::PI;
let gl = angle.cos();
let gr = angle.sin();
for i in 0..ctx.frames {
ctx.outputs[0][i] = ctx.inputs[0][i] * gl;
ctx.outputs[1][i] = ctx.inputs[1][i] * gr;
}
}
fn reset(&mut self) {}
fn params(&self) -> Vec<ParamDescriptor> {
vec![ParamDescriptor {
id: 0,
name: "Pan",
min: -1.0,
max: 1.0,
default: 0.0,
unit: ParamUnit::Linear,
flags: ParamFlags::BIPOLAR,
step: 0.05,
group: None,
help: "",
}]
}
fn get_param(&self, id: u32) -> f64 {
match id {
0 => self.pan as f64,
_ => 0.0,
}
}
fn set_param(&mut self, id: u32, value: f64) {
match id {
0 => self.pan = value.clamp(-1.0, 1.0) as f32,
_ => {}
}
}
}
pub struct MonoGain {
pub level: f32,
}
impl MonoGain {
pub fn new(level: f32) -> Self {
Self { level }
}
}
impl Processor for MonoGain {
fn info(&self) -> ProcessorInfo {
ProcessorInfo {
name: "mono_gain",
sig: Sig::MONO,
description: "Simple mono level control",
}
}
fn process(&mut self, ctx: &mut ProcessContext) {
for i in 0..ctx.frames {
ctx.outputs[0][i] = ctx.inputs[0][i] * self.level;
}
}
fn reset(&mut self) {}
fn params(&self) -> Vec<ParamDescriptor> {
vec![ParamDescriptor {
id: 0,
name: "Level",
min: 0.0,
max: 2.0,
default: 1.0,
unit: ParamUnit::Linear,
flags: ParamFlags::NONE,
step: 0.05,
group: None,
help: "",
}]
}
fn get_param(&self, id: u32) -> f64 {
match id {
0 => self.level as f64,
_ => 0.0,
}
}
fn set_param(&mut self, id: u32, value: f64) {
match id {
0 => self.level = value.clamp(0.0, 2.0) as f32,
_ => {}
}
}
}