pub struct NotificationHandler { channel: tokio::sync::broadcast::Sender, } #[derive(Clone, Debug)] pub enum JackNotification { Shutdown { status: jack::ClientStatus, reason: String, }, PortConnect { port_a: String, port_b: String, connected: bool, }, PortRegistered {}, } impl NotificationHandler { pub fn new() -> Self { let (channel, _) = tokio::sync::broadcast::channel(16); Self { channel } } pub fn subscribe(&self) -> tokio::sync::broadcast::Receiver { self.channel.subscribe() } } impl jack::NotificationHandler for NotificationHandler { unsafe fn shutdown(&mut self, status: jack::ClientStatus, reason: &str) { let reason = reason.to_string(); self.channel .send(JackNotification::Shutdown { status, reason }) .expect("Could not send shutdown notification"); } fn ports_connected( &mut self, client: &jack::Client, port_id_a: jack::PortId, port_id_b: jack::PortId, connect: bool, ) { // Convert port IDs to port names let Some(port_a) = client.port_by_id(port_id_a) else { return; }; let Ok(port_a) = port_a.name() else { return }; let Some(port_b) = client.port_by_id(port_id_b) else { return; }; let Ok(port_b) = port_b.name() else { return }; let notification = JackNotification::PortConnect { port_a, port_b, connected: connect, }; self.channel .send(notification) .expect("Could not send port connection notification"); } fn port_registration(&mut self, client: &jack::Client, port_id: jack::PortId, register: bool) { let Some(port_name) = client.port_by_id(port_id) else { return; }; let Ok(port_name) = port_name.name() else { return; }; if register { let notification = JackNotification::PortRegistered {}; self.channel .send(notification) .expect("Could not send port registration notification"); }; } }