WIP: prepare the ground for audio rate modulation

This commit is contained in:
2026-02-07 12:08:11 +01:00
parent 5758b18d58
commit c72733bac8
7 changed files with 260 additions and 1 deletions

View File

@@ -1103,6 +1103,52 @@ impl Forth {
}
}
Op::ModLfo(shape) => {
let period = stack.pop().ok_or("stack underflow")?.as_float()? * ctx.step_duration();
let max = stack.pop().ok_or("stack underflow")?.as_float()?;
let min = stack.pop().ok_or("stack underflow")?.as_float()?;
let suffix = match shape { 1 => "t", 2 => "w", 3 => "q", _ => "" };
let s = format!("{min}~{max}:{period}{suffix}");
stack.push(Value::Str(s.into(), None));
}
Op::ModSlide(curve) => {
let dur = stack.pop().ok_or("stack underflow")?.as_float()? * ctx.step_duration();
let end = stack.pop().ok_or("stack underflow")?.as_float()?;
let start = stack.pop().ok_or("stack underflow")?.as_float()?;
let suffix = match curve { 1 => "e", 2 => "s", _ => "" };
let s = format!("{start}>{end}:{dur}{suffix}");
stack.push(Value::Str(s.into(), None));
}
Op::ModRnd(dist) => {
let period = stack.pop().ok_or("stack underflow")?.as_float()? * ctx.step_duration();
let max = stack.pop().ok_or("stack underflow")?.as_float()?;
let min = stack.pop().ok_or("stack underflow")?.as_float()?;
let suffix = match dist { 1 => "s", 2 => "d", _ => "" };
let s = format!("{min}?{max}:{period}{suffix}");
stack.push(Value::Str(s.into(), None));
}
Op::ModEnv => {
if stack.is_empty() {
return Err("stack underflow".into());
}
let values = std::mem::take(stack);
let mut floats = Vec::with_capacity(values.len());
for v in &values {
floats.push(v.as_float()?);
}
if floats.len() < 3 || (floats.len() - 1) % 2 != 0 {
return Err("env expects: start target1 dur1 [target2 dur2 ...]".into());
}
let step_dur = ctx.step_duration();
use std::fmt::Write;
let mut s = String::new();
let _ = write!(&mut s, "{}", floats[0]);
for pair in floats[1..].chunks(2) {
let _ = write!(&mut s, ">{}:{}", pair[0], pair[1] * step_dur);
}
stack.push(Value::Str(s.into(), None));
}
// MIDI operations
Op::MidiEmit => {
let (_, params) = cmd.snapshot().unwrap_or((None, &[]));