From 99992fe78c61be5e43234a4e034decebd6f9d2df Mon Sep 17 00:00:00 2001 From: Royce Date: Sat, 10 Oct 2026 23:23:17 +0800 Subject: [PATCH] fix(mix): push an instrument's stored params to its plugin before each block (#152) When a session is reopened with a saved instrument-level change such as 'level = -12 dB', the value sat in t.instrument.params but was never written to the live plugin instance, so the bounce produced the same audio as the default (-6 dB). The inserts loop already calls apply_params per block; the instrument branch did not. Call apply_params(slot, ins, t, INSTRUMENT_SLOT, pos) before each instrument's process() so a saved level (or any other param set via 'mix.insert_state') reaches the plugin exactly the way insert params do. Refs #152. --- crates/mix/src/lib.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crates/mix/src/lib.rs b/crates/mix/src/lib.rs index 70cdd1c7..64ab1406 100644 --- a/crates/mix/src/lib.rs +++ b/crates/mix/src/lib.rs @@ -826,6 +826,14 @@ fn process_strip( } TrackKind::Instrument | TrackKind::Midi => { if let Some(inst) = &mut strip.instrument { + // #152: push the instrument's stored parameter values into the live plugin + // before processing, the same way inserts do below. Without this, the values + // loaded from a session (or set via `mix.insert_state`) never reach the plugin + // instance and the rendered audio matches the plugin's defaults — e.g. a saved + // `level = -12 dB` sounds the same as `level = -6 dB`. + if let Some(ins) = &t.instrument { + apply_params(inst, ins, t, INSTRUMENT_SLOT, pos); + } schedule_notes(s, t, pos, frames, inst, &mut strip.held); if strip.buf.len() >= 2 { inst.plugin.process(&mut strip.buf, frames);