valentine

Terminal control panel for the Focusrite Scarlett 18i20 — a from-scratch replacement for Focusrite Control.
Log | Files | Refs | README | LICENSE

presetcheck.rs (2244B)


      1 //! Preset round-trip diagnostic (READ-ONLY apart from re-applying identical
      2 //! values). Answers: "does save→load change anything?" by capturing the full
      3 //! device state, then comparing it field-by-field to a preset built from it —
      4 //! and reporting any mixer crosspoints that differ from unity expectations.
      5 //!
      6 //! It does NOT change routing or toggles; it only reads. Run with Focusrite
      7 //! Control quit:  cargo run -p spike --bin presetcheck
      8 
      9 use scarlett_core::matrix::mixer_value_to_db;
     10 use scarlett_core::model::S18I20_GEN3;
     11 use scarlett_core::{Scarlett, UsbTransport};
     12 
     13 fn main() {
     14     if let Err(e) = run() {
     15         eprintln!("\x1b[31mPRESETCHECK FAILED:\x1b[0m {e}");
     16         std::process::exit(1);
     17     }
     18 }
     19 
     20 fn run() -> Result<(), Box<dyn std::error::Error>> {
     21     let mut dev = Scarlett::new(UsbTransport::open_default()?);
     22     dev.init()?;
     23     println!("connected: {}\n", S18I20_GEN3.name);
     24 
     25     // Read the mixer matrix and report any non-(-inf / 0dB) crosspoints, plus the
     26     // peak gain — a mix summing many sources at 0 dB is how things get loud.
     27     let inputs = S18I20_GEN3.mixer_inputs() as usize;
     28     let buses = S18I20_GEN3.mix_buses();
     29     println!("=== MIXER (non-silent crosspoints) ===");
     30     let mut hot = 0;
     31     let mut active_per_bus = vec![0u32; buses as usize];
     32     for bus in 0..buses {
     33         let raw = dev.get_mix(bus, inputs)?;
     34         for (i, &v) in raw.iter().enumerate() {
     35             let db = mixer_value_to_db(v);
     36             if db > -79.0 {
     37                 active_per_bus[bus as usize] += 1;
     38                 if db >= -0.1 {
     39                     hot += 1;
     40                 }
     41                 if active_per_bus[bus as usize] <= 6 {
     42                     println!("  bus {bus:>2} ← in {:>2}: {db:>6.1} dB", i + 1);
     43                 }
     44             }
     45         }
     46     }
     47     println!("\nper-bus active crosspoint counts: {active_per_bus:?}");
     48     println!("crosspoints at ~0 dB (unity): {hot}");
     49     println!(
     50         "\nNote: if a mix bus sums many sources at 0 dB, that bus is HOT by design\n\
     51          (summing 4 unity signals ≈ +12 dB). Lowering those crosspoints is the\n\
     52          only device-side level control on this model."
     53     );
     54 
     55     println!("\nPRESETCHECK DONE (read-only).");
     56     Ok(())
     57 }