Feat: adding LPG
This commit is contained in:
@@ -135,6 +135,7 @@ pub enum Op {
|
||||
ModEnv,
|
||||
ModEnvAd,
|
||||
ModEnvAdr,
|
||||
Lpg,
|
||||
// Global params
|
||||
EmitAll,
|
||||
ClearGlobal,
|
||||
|
||||
@@ -1481,6 +1481,22 @@ impl Forth {
|
||||
stack.push(Value::Str(s.into(), None));
|
||||
}
|
||||
|
||||
Op::Lpg => {
|
||||
let depth = pop_float(stack)?.clamp(0.0, 1.0);
|
||||
let max = pop_float(stack)?;
|
||||
let min = pop_float(stack)?;
|
||||
let effective_max = min + (max - min) * depth;
|
||||
let sd = ctx.step_duration();
|
||||
let a = cmd_param_float(cmd, "attack").unwrap_or(0.0) * sd;
|
||||
let d = cmd_param_float(cmd, "decay").unwrap_or(1.0) * sd;
|
||||
let s = cmd_param_float(cmd, "sustain").unwrap_or(0.0);
|
||||
let r = cmd_param_float(cmd, "release").unwrap_or(0.0) * sd;
|
||||
use std::fmt::Write;
|
||||
let mut mod_str = String::new();
|
||||
let _ = write!(&mut mod_str, "{min}^{effective_max}:{a}:{d}:{s}:{r}");
|
||||
cmd.set_param("lpf", Value::Str(mod_str.into(), None));
|
||||
}
|
||||
|
||||
// MIDI operations
|
||||
Op::MidiEmit => {
|
||||
let (_, params) = cmd.snapshot().unwrap_or((None, &[]));
|
||||
@@ -1726,6 +1742,14 @@ fn extract_dev_param(params: &[(&str, Value)]) -> u8 {
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
fn cmd_param_float(cmd: &CmdRegister, name: &str) -> Option<f64> {
|
||||
cmd.params()
|
||||
.iter()
|
||||
.rev()
|
||||
.find(|(k, _)| *k == name)
|
||||
.and_then(|(_, v)| v.as_float().ok())
|
||||
}
|
||||
|
||||
fn is_tempo_scaled_param(name: &str) -> bool {
|
||||
matches!(
|
||||
name,
|
||||
|
||||
@@ -145,6 +145,7 @@ pub(super) fn simple_op(name: &str) -> Option<Op> {
|
||||
"ead" => Op::ModEnvAd,
|
||||
"eadr" => Op::ModEnvAdr,
|
||||
"eadsr" | "env" => Op::ModEnv,
|
||||
"lpg" => Op::Lpg,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -862,4 +862,14 @@ pub(super) const WORDS: &[Word] = &[
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
Word {
|
||||
name: "lpg",
|
||||
aliases: &[],
|
||||
category: "Audio Modulation",
|
||||
stack: "(min max depth --)",
|
||||
desc: "Low pass gate: pairs amp envelope with lpf modulation",
|
||||
example: "0.01 0.1 ad 200 8000 1 lpg .",
|
||||
compile: Simple,
|
||||
varargs: false,
|
||||
},
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user