commit acf91fce8cecdf5ac8d5aabb9e20601124513252
parent d3394aa85a304fca36ade45a3e9e114bdcbc0ccb
Author: Matthew Gantenbein <ganten1998@gmail.com>
Date: Mon, 1 Jun 2026 15:59:37 -0500
feat(spike): adatverify — fresh-process read of actual ADAT routing
Reads (no writes) what truly feeds each ADAT out, to confirm whether the
device accepted ADAT<-Mix or silently kept ADAT<-PCM. Run after adatset to
distinguish 'write not applied' from 'mix bus not attenuating'.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Diffstat:
2 files changed, 61 insertions(+), 0 deletions(-)
diff --git a/spike/Cargo.toml b/spike/Cargo.toml
@@ -55,3 +55,7 @@ scarlett-core = { path = "../scarlett-core" }
[[bin]]
name = "adatset"
path = "src/bin/adatset.rs"
+
+[[bin]]
+name = "adatverify"
+path = "src/bin/adatverify.rs"
diff --git a/spike/src/bin/adatverify.rs b/spike/src/bin/adatverify.rs
@@ -0,0 +1,57 @@
+//! Fresh-read ADAT routing verifier. Opens the device, reads routing, prints
+//! what ACTUALLY feeds each ADAT output — no writes at all. Run this AFTER
+//! `adatset -- -80` (in a separate process) to see whether the device truly
+//! accepted ADAT Out ← Mix, or silently kept ADAT Out ← PCM.
+//!
+//! cargo run -p spike --bin adatverify
+
+use scarlett_core::model::S18I20_GEN3;
+use scarlett_core::mux::{id_to_num, num_dsts, num_to_id, Dir, MuxState, PORT_COUNT_18I20_GEN3};
+use scarlett_core::ports::source_name;
+use scarlett_core::{Scarlett, UsbTransport};
+
+fn main() {
+ if let Err(e) = run() {
+ eprintln!("\x1b[31mADATVERIFY FAILED:\x1b[0m {e}");
+ std::process::exit(1);
+ }
+}
+
+fn run() -> Result<(), Box<dyn std::error::Error>> {
+ let mut dev = Scarlett::new(UsbTransport::open_default()?);
+ dev.init()?;
+ let pc = PORT_COUNT_18I20_GEN3;
+ let entries = dev.get_mux(num_dsts(&pc))?;
+ let st = MuxState::from_entries(pc, &entries);
+
+ println!("FRESH read — what actually feeds each ADAT output:");
+ let mut via_mix = 0;
+ for i in 0..8u16 {
+ let out = id_to_num(&pc, Dir::Out, 0x200 + i).unwrap_or(0);
+ let src_hw = num_to_id(&pc, Dir::In, st.get(out));
+ let is_mix = (src_hw & 0xf00) == 0x300;
+ if is_mix {
+ via_mix += 1;
+ }
+ println!(" ADAT Out {} ← {}", i + 1, source_name(src_hw));
+ }
+ println!(
+ "\n{}/8 ADAT outs via mixer.\n{}",
+ via_mix,
+ if via_mix == 8 {
+ "Device DID accept ADAT←Mix. So if -80 still played, the Mix bus itself\n\
+ is NOT attenuating — the mixer isn't in the ADAT signal path as assumed."
+ } else if via_mix == 0 {
+ "Device kept ADAT←PCM despite the write 'succeeding' — the route write is\n\
+ NOT taking on ADAT outputs (the bug). Our get_mux read back our own\n\
+ optimistic value earlier; the device never applied it."
+ } else {
+ "Partial — some ADAT outs took the route, some didn't."
+ }
+ );
+
+ // Also show the meter so we can see if ADAT-feeding PCM is even active.
+ println!("\n(For reference, this is read-only — no writes made.)");
+ let _ = S18I20_GEN3.name;
+ Ok(())
+}