91 lines
2.7 KiB
Rust
91 lines
2.7 KiB
Rust
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<jack::AudioIn>,
|
|
pub audio_out: jack::Port<jack::AudioOut>,
|
|
pub midi_in: jack::Port<jack::MidiIn>,
|
|
}
|
|
|
|
#[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)
|
|
} |