mod allocator; mod audio_chunk; mod chunk_factory; mod looper_error; mod midi; mod notification_handler; mod process_handler; mod track; use std::sync::Arc; use allocator::Allocator; use audio_chunk::AudioChunk; use chunk_factory::ChunkFactory; use looper_error::LooperError; use looper_error::Result; use notification_handler::JackNotification; use notification_handler::NotificationHandler; use process_handler::ProcessHandler; use track::Track; use track::TrackState; pub struct JackPorts { pub audio_in: jack::Port, pub audio_out: jack::Port, pub midi_in: jack::Port, } #[tokio::main] async fn main() { simple_logger::SimpleLogger::new().init().expect("Could not initialize logger"); let (jack_client, ports) = setup_jack(); let (allocator, factory_handle) = Allocator::spawn(jack_client.sample_rate(), 3); let process_handler = ProcessHandler::new(ports, allocator) .expect("Could not create process handler"); let notification_handler = NotificationHandler::new(); let mut notification_channel = notification_handler.subscribe(); let _async_client = jack_client .activate_async(notification_handler, process_handler) .expect("Could not activate Jack"); tokio::select! { notification = notification_channel.recv() => { match notification { Ok(JackNotification::Shutdown {reason, status}) => { log::error!("Jack shutdown: {reason} {status:?}"); } Err(e) => { log::error!("NotificationHandler stopped: {e}"); } } } _ = factory_handle => { log::error!("Allocator was dropped"); } _ = tokio::signal::ctrl_c() => { log::info!("Stopping"); } } } fn setup_jack() -> (jack::Client, JackPorts) { let (jack_client, jack_status) = jack::Client::new("looper", jack::ClientOptions::NO_START_SERVER) .expect("Could not create Jack client"); if !jack_status.is_empty() { panic!("Could not start jack client: {jack_status:?}"); } let audio_in = jack_client .register_port("audio_in", jack::AudioIn::default()) .expect("Could not create audio_in port"); let audio_out = jack_client .register_port("audio_out", jack::AudioOut::default()) .expect("Could not create audio_out port"); let midi_in = jack_client .register_port("midi_in", jack::MidiIn::default()) .expect("Could not create midi_in port"); let ports = JackPorts { audio_in, audio_out, midi_in, }; (jack_client, ports) }