Feat: polyphony + iterator reset
Some checks failed
Deploy Website / deploy (push) Failing after 4m48s
Some checks failed
Deploy Website / deploy (push) Failing after 4m48s
This commit is contained in:
@@ -152,6 +152,23 @@ impl Forth {
|
||||
select_and_run(selected, stack, outputs, cmd)
|
||||
};
|
||||
|
||||
let compute_poly_count = |cmd: &CmdRegister| -> usize {
|
||||
let sound_len = match cmd.sound() {
|
||||
Some(Value::CycleList(items)) => items.len(),
|
||||
_ => 1,
|
||||
};
|
||||
let param_max = cmd
|
||||
.params()
|
||||
.iter()
|
||||
.map(|(_, v)| match v {
|
||||
Value::CycleList(items) => items.len(),
|
||||
_ => 1,
|
||||
})
|
||||
.max()
|
||||
.unwrap_or(1);
|
||||
sound_len.max(param_max)
|
||||
};
|
||||
|
||||
let emit_with_cycling = |cmd: &CmdRegister,
|
||||
emit_idx: usize,
|
||||
delta_secs: f64,
|
||||
@@ -363,38 +380,56 @@ impl Forth {
|
||||
}
|
||||
|
||||
Op::NewCmd => {
|
||||
let val = stack.pop().ok_or("stack underflow")?;
|
||||
if stack.is_empty() {
|
||||
return Err("stack underflow".into());
|
||||
}
|
||||
let values = std::mem::take(stack);
|
||||
let val = if values.len() == 1 {
|
||||
values.into_iter().next().unwrap()
|
||||
} else {
|
||||
Value::CycleList(values)
|
||||
};
|
||||
cmd.set_sound(val);
|
||||
}
|
||||
Op::SetParam(param) => {
|
||||
let val = stack.pop().ok_or("stack underflow")?;
|
||||
if stack.is_empty() {
|
||||
return Err("stack underflow".into());
|
||||
}
|
||||
let values = std::mem::take(stack);
|
||||
let val = if values.len() == 1 {
|
||||
values.into_iter().next().unwrap()
|
||||
} else {
|
||||
Value::CycleList(values)
|
||||
};
|
||||
cmd.set_param(param.clone(), val);
|
||||
}
|
||||
|
||||
Op::Emit => {
|
||||
let poly_count = compute_poly_count(cmd);
|
||||
let deltas = if cmd.deltas().is_empty() {
|
||||
vec![Value::Float(0.0, None)]
|
||||
} else {
|
||||
cmd.deltas().to_vec()
|
||||
};
|
||||
|
||||
for (emit_idx, delta_val) in deltas.iter().enumerate() {
|
||||
let delta_frac = delta_val.as_float()?;
|
||||
let delta_secs = ctx.nudge_secs + delta_frac * ctx.step_duration();
|
||||
// Record delta span for highlighting
|
||||
if let Some(span) = delta_val.span() {
|
||||
if let Some(trace) = trace_cell.borrow_mut().as_mut() {
|
||||
trace.selected_spans.push(span);
|
||||
}
|
||||
}
|
||||
if let Some(sound_val) =
|
||||
emit_with_cycling(cmd, emit_idx, delta_secs, outputs)?
|
||||
{
|
||||
if let Some(span) = sound_val.span() {
|
||||
for poly_idx in 0..poly_count {
|
||||
for delta_val in deltas.iter() {
|
||||
let delta_frac = delta_val.as_float()?;
|
||||
let delta_secs = ctx.nudge_secs + delta_frac * ctx.step_duration();
|
||||
if let Some(span) = delta_val.span() {
|
||||
if let Some(trace) = trace_cell.borrow_mut().as_mut() {
|
||||
trace.selected_spans.push(span);
|
||||
}
|
||||
}
|
||||
if let Some(sound_val) =
|
||||
emit_with_cycling(cmd, poly_idx, delta_secs, outputs)?
|
||||
{
|
||||
if let Some(span) = sound_val.span() {
|
||||
if let Some(trace) = trace_cell.borrow_mut().as_mut() {
|
||||
trace.selected_spans.push(span);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -503,19 +538,6 @@ impl Forth {
|
||||
drain_select_run(count, idx, stack, outputs, cmd)?;
|
||||
}
|
||||
|
||||
Op::TCycle => {
|
||||
let count = stack.pop().ok_or("stack underflow")?.as_int()? as usize;
|
||||
if count == 0 {
|
||||
return Err("tcycle count must be > 0".into());
|
||||
}
|
||||
if stack.len() < count {
|
||||
return Err("stack underflow".into());
|
||||
}
|
||||
let start = stack.len() - count;
|
||||
let values: Vec<Value> = stack.drain(start..).collect();
|
||||
stack.push(Value::CycleList(values));
|
||||
}
|
||||
|
||||
Op::Choose => {
|
||||
let count = stack.pop().ok_or("stack underflow")?.as_int()? as usize;
|
||||
if count == 0 {
|
||||
@@ -692,27 +714,10 @@ impl Forth {
|
||||
}
|
||||
|
||||
Op::At => {
|
||||
let top = stack.pop().ok_or("stack underflow")?;
|
||||
let deltas = match &top {
|
||||
Value::Float(..) => vec![top],
|
||||
Value::Int(n, _) => {
|
||||
let count = *n as usize;
|
||||
if stack.len() < count {
|
||||
return Err(format!(
|
||||
"at: stack underflow, expected {} values but got {}",
|
||||
count,
|
||||
stack.len()
|
||||
));
|
||||
}
|
||||
let mut vals = Vec::with_capacity(count);
|
||||
for _ in 0..count {
|
||||
vals.push(stack.pop().ok_or("stack underflow")?);
|
||||
}
|
||||
vals.reverse();
|
||||
vals
|
||||
}
|
||||
_ => return Err("at expects float or int count".into()),
|
||||
};
|
||||
if stack.is_empty() {
|
||||
return Err("stack underflow".into());
|
||||
}
|
||||
let deltas = std::mem::take(stack);
|
||||
cmd.set_deltas(deltas);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user