adatfader.rs (3505B)
1 //! ADAT-fader chain diagnostic. Runs the exact via-mixer + level sequence the 2 //! TUI does, reading device state back at each step so we can see precisely 3 //! where the fader chain breaks. Restores ADAT to direct-from-DAW at the end. 4 //! 5 //! Run with Focusrite Control quit: cargo run -p spike --bin adatfader 6 7 use scarlett_core::matrix::mixer_value_to_db; 8 use scarlett_core::model::S18I20_GEN3; 9 use scarlett_core::mux::{id_to_num, num_dsts, num_to_id, Dir, MuxState, PORT_COUNT_18I20_GEN3}; 10 use scarlett_core::ports::source_name; 11 use scarlett_core::{Scarlett, UsbTransport}; 12 13 fn main() { 14 if let Err(e) = run() { 15 eprintln!("\x1b[31mADATFADER FAILED:\x1b[0m {e}"); 16 std::process::exit(1); 17 } 18 } 19 20 fn adat_group() -> &'static scarlett_core::matrix::MonitorGroup { 21 scarlett_core::matrix::MONITOR_GROUPS 22 .iter() 23 .find(|g| g.name.starts_with("ADAT")) 24 .expect("ADAT group exists") 25 } 26 27 fn show_adat_routing(dev: &mut Scarlett<UsbTransport>, pc: [(u16, u16); 6], tag: &str) { 28 let entries = dev.get_mux(num_dsts(&pc)).unwrap(); 29 let st = MuxState::from_entries(pc, &entries); 30 println!("--- ADAT Out routing [{tag}] ---"); 31 for i in 0..8u16 { 32 let out = id_to_num(&pc, Dir::Out, 0x200 + i).unwrap_or(0); 33 let src = num_to_id(&pc, Dir::In, st.get(out)); 34 println!(" ADAT Out {} ← {}", i + 1, source_name(src)); 35 } 36 } 37 38 fn run() -> Result<(), Box<dyn std::error::Error>> { 39 let mut dev = Scarlett::new(UsbTransport::open_default()?); 40 dev.init()?; 41 let pc = PORT_COUNT_18I20_GEN3; 42 let g = adat_group(); 43 let inputs = S18I20_GEN3.mixer_inputs() as usize; 44 println!("connected: {}\n", S18I20_GEN3.name); 45 46 show_adat_routing(&mut dev, pc, "before"); 47 48 // Step 1: route ADAT via mixer. 49 println!("\n>>> route_group_via_mixer(ADAT)"); 50 dev.route_group_via_mixer(pc, g)?; 51 show_adat_routing(&mut dev, pc, "after via-mixer"); 52 53 // What feeds the ADAT mixer-inputs now? 54 let entries = dev.get_mux(num_dsts(&pc))?; 55 let st = MuxState::from_entries(pc, &entries); 56 println!("--- ADAT mixer-input feeds ---"); 57 for i in 0..g.count { 58 let mi = id_to_num(&pc, Dir::Out, 0x300 + g.mix_in_base + i).unwrap_or(0); 59 let src = num_to_id(&pc, Dir::In, st.get(mi)); 60 println!(" MixerIn {} ← {}", g.mix_in_base + i + 1, source_name(src)); 61 } 62 63 // Step 2: set group level to -40 dB and read the buses back. 64 println!("\n>>> set_group_level(ADAT, -40 dB)"); 65 dev.set_group_level(g, -40.0, inputs)?; 66 for i in 0..g.count { 67 let bus = g.bus_base + i; 68 let raw = dev.get_mix(bus, inputs)?; 69 let in_idx = (g.mix_in_base + i) as usize; 70 let this = raw.get(in_idx).map(|&v| mixer_value_to_db(v)).unwrap_or(-99.0); 71 let nonzero = raw.iter().filter(|&&v| v > 0).count(); 72 println!( 73 " Mix bus {bus:>2}: input {} = {this:>6.1} dB ({nonzero} non-silent inputs total)", 74 in_idx + 1 75 ); 76 } 77 78 println!( 79 "\nEXPECTED: ADAT Out ← Mix C..J; MixerIn ← PCM 13..20; each bus shows its\n\ 80 one input at -40 dB. If routing still shows ← PCM, the route write failed.\n\ 81 If the bus input isn't -40, the level write/index is wrong." 82 ); 83 84 // Restore: ADAT back to direct from DAW. 85 println!("\n>>> restoring ADAT to direct-from-DAW"); 86 dev.route_group_direct(pc, g)?; 87 show_adat_routing(&mut dev, pc, "restored"); 88 89 println!("\nADATFADER DONE."); 90 Ok(()) 91 }