use tek::*; use clap::{self, Parser, Subcommand}; #[derive(Debug, Parser)] #[command(version, about, long_about = None)] pub struct TekCli { /// Which app to initialize #[command(subcommand)] mode: TekMode, /// Name of JACK client #[arg(short='n', long)] name: Option, /// Whether to attempt to become transport master #[arg(short='S', long, default_value_t = false)] sync_lead: bool, /// Whether to sync to external transport master #[arg(short='s', long, default_value_t = true)] sync_follow: bool, /// Initial tempo in beats per minute #[arg(short='b', long, default_value = None)] bpm: Option, /// Whether to include a transport toolbar (default: true) #[arg(short='t', long, default_value_t = true)] show_clock: bool, /// MIDI outs to connect to (multiple instances accepted) #[arg(short='I', long)] midi_from: Vec, /// MIDI outs to connect to (multiple instances accepted) #[arg(short='i', long)] midi_from_re: Vec, /// MIDI ins to connect to (multiple instances accepted) #[arg(short='O', long)] midi_to: Vec, /// MIDI ins to connect to (multiple instances accepted) #[arg(short='o', long)] midi_to_re: Vec, /// Audio outs to connect to left input #[arg(short='l', long)] left_from: Vec, /// Audio outs to connect to right input #[arg(short='r', long)] right_from: Vec, /// Audio ins to connect from left output #[arg(short='L', long)] left_to: Vec, /// Audio ins to connect from right output #[arg(short='R', long)] right_to: Vec, } #[derive(Debug, Clone, Subcommand)] pub enum TekMode { /// A standalone transport clock. Clock, /// A MIDI sequencer. Sequencer, /// A MIDI-controlled audio sampler. Sampler, /// Sequencer and sampler together.12 Groovebox, /// Multi-track MIDI sequencer. Arranger { /// Number of scenes #[arg(short = 'y', long, default_value_t = 1)] scenes: usize, /// Number of tracks #[arg(short = 'x', long, default_value_t = 1)] tracks: usize, /// Width of tracks #[arg(short = 'w', long, default_value_t = 9)] track_width: usize, }, /// TODO: A MIDI-controlled audio mixer Mixer, /// TODO: A customizable channel strip Track, /// TODO: An audio plugin host Plugin, } /// Application entrypoint. pub fn main () -> Usually<()> { let cli = TekCli::parse(); let name = cli.name.as_ref().map_or("tek", |x|x.as_str()); //let color = ItemPalette::random(); let jack = JackConnection::new(name)?; let engine = Tui::new()?; let empty = &[] as &[&str]; let midi_froms = PortConnection::collect(&cli.midi_from, &cli.midi_from_re, empty); let midi_tos = PortConnection::collect(&cli.midi_to, &cli.midi_to_re, empty); let left_froms = PortConnection::collect(&cli.left_from, empty, empty); let left_tos = PortConnection::collect(&cli.left_to, empty, empty); let right_froms = PortConnection::collect(&cli.right_from, empty, empty); let right_tos = PortConnection::collect(&cli.right_to, empty, empty); let audio_froms = &[left_froms.as_slice(), right_froms.as_slice()]; let audio_tos = &[left_tos.as_slice(), right_tos.as_slice() ]; Ok(match cli.mode { TekMode::Clock => engine.run(&jack.activate_with(|jack|App::clock( jack, cli.bpm))?)?, TekMode::Sequencer => engine.run(&jack.activate_with(|jack|App::sequencer( jack, cli.bpm, &midi_froms, &midi_tos))?)?, TekMode::Groovebox => engine.run(&jack.activate_with(|jack|App::groovebox( jack, cli.bpm, &midi_froms, &midi_tos, &audio_froms, &audio_tos))?)?, TekMode::Arranger { scenes, tracks, track_width, .. } => engine.run(&jack.activate_with(|jack|App::arranger( jack, cli.bpm, &midi_froms, &midi_tos, &audio_froms, &audio_tos, scenes, tracks, track_width, ))?)?, //TekMode::Sampler => engine.run(&jack.activate_with(|jack|Ok( //SamplerTui { //cursor: (0, 0), //editing: None, //mode: None, //note_lo: 36.into(), //note_pt: 36.into(), //size: Measure::new(), //state: Sampler::new(jack, &"sampler", &midi_froms, //&[&left_froms, &right_froms], //&[&left_tos, &right_tos])?, //color, //} //))?)?, _ => todo!() }) } #[test] fn verify_cli () { use clap::CommandFactory; TekCli::command().debug_assert(); }