tek/crates/jack/src/jack_device.rs

86 lines
2.9 KiB
Rust

use crate::*
/// A [AudioComponent] bound to a JACK client and a set of ports.
pub struct JackDevice<E: Engine> {
/// The active JACK client of this device.
pub client: DynamicAsyncClient,
/// The device state, encapsulated for sharing between threads.
pub state: Arc<RwLock<Box<dyn AudioComponent<E>>>>,
/// Unowned copies of the device's JACK ports, for connecting to the device.
/// The "real" readable/writable `Port`s are owned by the `state`.
pub ports: UnownedJackPorts,
}
impl<E: Engine> std::fmt::Debug for JackDevice<E> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("JackDevice")
.field("ports", &self.ports)
.finish()
}
}
impl<E: Engine> Render for JackDevice<E> {
type Engine = E;
fn min_size(&self, to: E::Size) -> Perhaps<E::Size> {
self.state.read().unwrap().layout(to)
}
fn render(&self, to: &mut E::Output) -> Usually<()> {
self.state.read().unwrap().render(to)
}
}
impl<E: Engine> Handle<E> for JackDevice<E> {
fn handle(&mut self, from: &E::Input) -> Perhaps<E::Handled> {
self.state.write().unwrap().handle(from)
}
}
impl<E: Engine> Ports for JackDevice<E> {
fn audio_ins(&self) -> Usually<Vec<&Port<Unowned>>> {
Ok(self.ports.audio_ins.values().collect())
}
fn audio_outs(&self) -> Usually<Vec<&Port<Unowned>>> {
Ok(self.ports.audio_outs.values().collect())
}
fn midi_ins(&self) -> Usually<Vec<&Port<Unowned>>> {
Ok(self.ports.midi_ins.values().collect())
}
fn midi_outs(&self) -> Usually<Vec<&Port<Unowned>>> {
Ok(self.ports.midi_outs.values().collect())
}
}
impl<E: Engine> JackDevice<E> {
/// Returns a locked mutex of the state's contents.
pub fn state(&self) -> LockResult<RwLockReadGuard<Box<dyn AudioComponent<E>>>> {
self.state.read()
}
/// Returns a locked mutex of the state's contents.
pub fn state_mut(&self) -> LockResult<RwLockWriteGuard<Box<dyn AudioComponent<E>>>> {
self.state.write()
}
pub fn connect_midi_in(&self, index: usize, port: &Port<Unowned>) -> Usually<()> {
Ok(self
.client
.as_client()
.connect_ports(port, self.midi_ins()?[index])?)
}
pub fn connect_midi_out(&self, index: usize, port: &Port<Unowned>) -> Usually<()> {
Ok(self
.client
.as_client()
.connect_ports(self.midi_outs()?[index], port)?)
}
pub fn connect_audio_in(&self, index: usize, port: &Port<Unowned>) -> Usually<()> {
Ok(self
.client
.as_client()
.connect_ports(port, self.audio_ins()?[index])?)
}
pub fn connect_audio_out(&self, index: usize, port: &Port<Unowned>) -> Usually<()> {
Ok(self
.client
.as_client()
.connect_ports(self.audio_outs()?[index], port)?)
}
}