commit c89c962772742c013271b3b881fc1f8ba948ce51
parent 4358539aeb5174202e6c812c014e725e629b9f93
Author: Matthew Gantenbein <ganten1998@gmail.com>
Date: Mon, 1 Jun 2026 13:51:45 -0500
feat: 'c' clears the mixer to silence (auto-backs-up first)
The device sits in a wall-of-unity mixer (288 crosspoints at 0 dB = up to
~+27 dB summing per bus) — a prime loudness suspect. Mixer tab 'c' saves the
current mixer to a 'mixer-backup' preset, then sets every crosspoint to
silence via Scarlett::clear_mixer. Reversible: load 'mixer-backup' with p.
Diagnostic step to confirm whether the mixer feeds the monitors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Diffstat:
3 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/scarlett-core/src/matrix.rs b/scarlett-core/src/matrix.rs
@@ -230,6 +230,17 @@ impl<T: Transport> Scarlett<T> {
Ok(())
}
+ /// Set every crosspoint of every mix bus to silence (all inputs off). This
+ /// is the bulk "clear mixer" — useful to tame a factory wall-of-unity matrix.
+ /// `buses`/`inputs` are the device's mix dimensions.
+ pub fn clear_mixer(&mut self, buses: u16, inputs: usize) -> Result<(), TransportError> {
+ let silence = vec![0u16; inputs];
+ for bus in 0..buses {
+ self.set_mix(bus, &silence)?;
+ }
+ Ok(())
+ }
+
/// Read every mix bus into a `buses × inputs` grid of dB gains (for a UI
/// refresh of the whole mixer matrix).
pub fn read_mixer_db(
diff --git a/valentine/src/main.rs b/valentine/src/main.rs
@@ -495,10 +495,32 @@ impl App {
KeyCode::Char('-') | KeyCode::Char('_') => self.nudge_mix(-1.0),
KeyCode::Char('0') => self.set_mix_abs(0.0),
KeyCode::Char('m') => self.set_mix_abs(scarlett_core::matrix::MIXER_MIN_DB),
+ KeyCode::Char('c') => self.clear_mixer(),
_ => {}
}
}
+ /// Clear the entire mixer to silence — but first auto-save the current mixer
+ /// to a `mixer-backup` preset so it's fully reversible (load it with `p`).
+ fn clear_mixer(&mut self) {
+ // Back up current mixer first.
+ self.save_preset_as("mixer-backup");
+ let inputs = S18I20_GEN3.mixer_inputs();
+ let buses = S18I20_GEN3.mix_buses();
+ let dev = match &mut self.device {
+ Ok(d) => d,
+ Err(_) => return,
+ };
+ match dev.scarlett.clear_mixer(buses, inputs as usize) {
+ Ok(()) => {
+ dev.mixer.clear(); // force reload on next view
+ self.status =
+ Some("mixer cleared (backup saved → 'mixer-backup'; p to restore)".into());
+ }
+ Err(e) => self.status = Some(format!("clear failed: {e}")),
+ }
+ }
+
fn nudge_mix(&mut self, delta: f32) {
let cur = self.mixer_cell();
self.set_mix_abs(mixer::clamp_db(cur + delta));
diff --git a/valentine/src/panels/mixer.rs b/valentine/src/panels/mixer.rs
@@ -152,7 +152,7 @@ pub fn render(
lines.push(Line::from(Span::styled(
format!(
- "↑↓←→ move +/- 1dB 0 unity m mute [in {}/{} bus {}/{}]",
+ "↑↓←→ move +/- 1dB 0 unity m mute c clear-all [in {}/{} bus {}/{}]",
cursor.input + 1,
inputs,
bus_label(cursor.bus),