mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
JackClient -> JackConnection
This commit is contained in:
parent
c3f9aa7549
commit
411d4bc91d
23 changed files with 55 additions and 51 deletions
|
|
@ -38,7 +38,7 @@ impl ArrangerCli {
|
|||
if let Some(name) = self.name.as_ref() {
|
||||
client_name = name.clone();
|
||||
}
|
||||
Tui::run(JackClient::new(client_name.as_str())?.activate_with(|jack|{
|
||||
Tui::run(JackConnection::new(client_name.as_str())?.activate_with(|jack|{
|
||||
let mut app = ArrangerTui::try_from(jack)?;
|
||||
let jack = jack.read().unwrap();
|
||||
app.color = ItemPalette::random();
|
||||
|
|
@ -50,7 +50,7 @@ impl ArrangerCli {
|
|||
}
|
||||
}
|
||||
|
||||
fn add_tracks (jack: &JackClient, app: &mut ArrangerTui, cli: &ArrangerCli) -> Usually<()> {
|
||||
fn add_tracks (jack: &JackConnection, app: &mut ArrangerTui, cli: &ArrangerCli) -> Usually<()> {
|
||||
let n = cli.tracks;
|
||||
let track_color_1 = ItemColor::random();
|
||||
let track_color_2 = ItemColor::random();
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ pub struct GrooveboxCli {
|
|||
}
|
||||
impl GrooveboxCli {
|
||||
fn run (&self) -> Usually<()> {
|
||||
Tui::run(JackClient::new("tek_groovebox")?.activate_with(|jack|{
|
||||
Tui::run(JackConnection::new("tek_groovebox")?.activate_with(|jack|{
|
||||
let app = tek::GrooveboxTui::try_from(jack)?;
|
||||
jack.read().unwrap().client().connect_ports(&app.player.midi_outs[0], &app.sampler.midi_in)?;
|
||||
jack.connect_midi_from(&app.player.midi_ins[0], &self.midi_from)?;
|
||||
|
|
@ -44,11 +44,10 @@ impl GrooveboxCli {
|
|||
jack.connect_audio_to(&app.sampler.audio_outs[0], &self.l_to)?;
|
||||
jack.connect_audio_to(&app.sampler.audio_outs[1], &self.r_to)?;
|
||||
if self.sync {
|
||||
jack.read().unwrap().client().register_timebase_callback(false, |state|{
|
||||
let ::jack::contrib::TimebaseInfo { state, new_pos, nframes, mut position } = state;
|
||||
app.clock().playhead.update_from_sample(position.frame() as f64);
|
||||
position.bbt = Some(app.clock().bbt());
|
||||
position
|
||||
jack.read().unwrap().client().register_timebase_callback(false, |mut state|{
|
||||
app.clock().playhead.update_from_sample(state.position.frame() as f64);
|
||||
state.position.bbt = Some(app.clock().bbt());
|
||||
state.position
|
||||
})?
|
||||
}
|
||||
Ok(app)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ pub fn main () -> Usually<()> { SamplerCli::parse().run() }
|
|||
}
|
||||
impl SamplerCli {
|
||||
fn run (&self) -> Usually<()> {
|
||||
Tui::run(JackClient::new("tek_sampler")?.activate_with(|x|{
|
||||
Tui::run(JackConnection::new("tek_sampler")?.activate_with(|x|{
|
||||
let sampler = tek::SamplerTui::try_from(x)?;
|
||||
Ok(sampler)
|
||||
})?)?;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ pub struct SequencerCli {
|
|||
impl SequencerCli {
|
||||
fn run (&self) -> Usually<()> {
|
||||
let name = self.name.as_deref().unwrap_or("tek_sequencer");
|
||||
Tui::run(JackClient::new(name)?.activate_with(|jack|{
|
||||
Tui::run(JackConnection::new(name)?.activate_with(|jack|{
|
||||
let mut app = SequencerTui::try_from(jack)?;
|
||||
let jack = jack.read().unwrap();
|
||||
let midi_in = jack.register_port("i", MidiIn::default())?;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ include!("./lib.rs");
|
|||
|
||||
/// Application entrypoint.
|
||||
pub fn main () -> Usually<()> {
|
||||
Tui::run(JackClient::new("tek_transport")?.activate_with(|jack|{
|
||||
Tui::run(JackConnection::new("tek_transport")?.activate_with(|jack|{
|
||||
TransportTui::try_from(jack)
|
||||
})?)?;
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#[allow(unused_imports)] use tek::{*, jack::*};
|
||||
|
||||
#[allow(unused)]
|
||||
fn connect_from (jack: &JackClient, input: &Port<MidiIn>, ports: &[String]) -> Usually<()> {
|
||||
fn connect_from (jack: &JackConnection, input: &Port<MidiIn>, ports: &[String]) -> Usually<()> {
|
||||
for port in ports.iter() {
|
||||
if let Some(port) = jack.port_by_name(port).as_ref() {
|
||||
jack.client().connect_ports(port, input)?;
|
||||
|
|
@ -15,7 +15,7 @@ fn connect_from (jack: &JackClient, input: &Port<MidiIn>, ports: &[String]) -> U
|
|||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn connect_to (jack: &JackClient, output: &Port<MidiOut>, ports: &[String]) -> Usually<()> {
|
||||
fn connect_to (jack: &JackConnection, output: &Port<MidiOut>, ports: &[String]) -> Usually<()> {
|
||||
for port in ports.iter() {
|
||||
if let Some(port) = jack.port_by_name(port).as_ref() {
|
||||
jack.client().connect_ports(output, port)?;
|
||||
|
|
@ -27,7 +27,7 @@ fn connect_to (jack: &JackClient, output: &Port<MidiOut>, ports: &[String]) -> U
|
|||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn connect_audio_from (jack: &JackClient, input: &Port<AudioIn>, ports: &[String]) -> Usually<()> {
|
||||
fn connect_audio_from (jack: &JackConnection, input: &Port<AudioIn>, ports: &[String]) -> Usually<()> {
|
||||
for port in ports.iter() {
|
||||
if let Some(port) = jack.port_by_name(port).as_ref() {
|
||||
jack.client().connect_ports(port, input)?;
|
||||
|
|
@ -39,7 +39,7 @@ fn connect_audio_from (jack: &JackClient, input: &Port<AudioIn>, ports: &[String
|
|||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn connect_audio_to (jack: &JackClient, output: &Port<AudioOut>, ports: &[String]) -> Usually<()> {
|
||||
fn connect_audio_to (jack: &JackConnection, output: &Port<AudioOut>, ports: &[String]) -> Usually<()> {
|
||||
for port in ports.iter() {
|
||||
if let Some(port) = jack.port_by_name(port).as_ref() {
|
||||
jack.client().connect_ports(output, port)?;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ pub fn main () -> Usually<()> {
|
|||
|
||||
impl MixerCli {
|
||||
fn run (&self) -> Usually<()> {
|
||||
Tui::run(JackClient::new("tek_mixer")?.activate_with(|jack|{
|
||||
Tui::run(JackConnection::new("tek_mixer")?.activate_with(|jack|{
|
||||
let mut mixer = Mixer::new(jack, self.name.as_ref().map(|x|x.as_str()).unwrap_or("mixer"))?;
|
||||
for channel in 0..self.channels.unwrap_or(8) {
|
||||
mixer.track_add(&format!("Track {}", channel + 1), 1)?;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ pub fn main () -> Usually<()> {
|
|||
|
||||
impl PluginCli {
|
||||
fn run (&self) -> Usually<()> {
|
||||
Tui::run(JackClient::new("tek_plugin")?.activate_with(|jack|{
|
||||
Tui::run(JackConnection::new("tek_plugin")?.activate_with(|jack|{
|
||||
let mut plugin = Plugin::new_lv2(
|
||||
jack,
|
||||
self.name.as_ref().map(|x|x.as_str()).unwrap_or("mixer"),
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ pub fn main () -> Usually<()> {
|
|||
|
||||
impl SamplerCli {
|
||||
fn run (&self) -> Usually<()> {
|
||||
Tui::run(JackClient::new("tek_sampler")?.activate_with(|jack|{
|
||||
Tui::run(JackConnection::new("tek_sampler")?.activate_with(|jack|{
|
||||
let mut plugin = Sampler::new(
|
||||
jack,
|
||||
self.name.as_ref().map(|x|x.as_str()).unwrap_or("mixer"),
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ mod arranger_h;
|
|||
|
||||
/// Root view for standalone `tek_arranger`
|
||||
pub struct ArrangerTui {
|
||||
jack: Arc<RwLock<JackClient>>,
|
||||
jack: Arc<RwLock<JackConnection>>,
|
||||
pub clock: ClockModel,
|
||||
pub phrases: PoolModel,
|
||||
pub tracks: Vec<ArrangerTrack>,
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ pub trait FromEdn<C>: Sized {
|
|||
}
|
||||
}
|
||||
|
||||
from_edn!("sampler" => |jack: &Arc<RwLock<JackClient>>, args| -> crate::Sampler {
|
||||
from_edn!("sampler" => |jack: &Arc<RwLock<JackConnection>>, args| -> crate::Sampler {
|
||||
let mut name = String::new();
|
||||
let mut dir = String::new();
|
||||
let mut samples = BTreeMap::new();
|
||||
|
|
@ -64,7 +64,7 @@ from_edn!("sampler" => |jack: &Arc<RwLock<JackClient>>, args| -> crate::Sampler
|
|||
|
||||
type MidiSample = (Option<u7>, Arc<RwLock<crate::Sample>>);
|
||||
|
||||
from_edn!("sample" => |(_jack, dir): (&Arc<RwLock<JackClient>>, &str), args| -> MidiSample {
|
||||
from_edn!("sample" => |(_jack, dir): (&Arc<RwLock<JackConnection>>, &str), args| -> MidiSample {
|
||||
let mut name = String::new();
|
||||
let mut file = String::new();
|
||||
let mut midi = None;
|
||||
|
|
@ -97,7 +97,7 @@ from_edn!("sample" => |(_jack, dir): (&Arc<RwLock<JackClient>>, &str), args| ->
|
|||
}))))
|
||||
});
|
||||
|
||||
from_edn!("plugin/lv2" => |jack: &Arc<RwLock<JackClient>>, args| -> Plugin {
|
||||
from_edn!("plugin/lv2" => |jack: &Arc<RwLock<JackConnection>>, args| -> Plugin {
|
||||
let mut name = String::new();
|
||||
let mut path = String::new();
|
||||
edn!(edn in args {
|
||||
|
|
@ -119,7 +119,7 @@ const SYM_GAIN: &str = ":gain";
|
|||
const SYM_SAMPLER: &str = "sampler";
|
||||
const SYM_LV2: &str = "lv2";
|
||||
|
||||
from_edn!("mixer/track" => |jack: &Arc<RwLock<JackClient>>, args| -> MixerTrack {
|
||||
from_edn!("mixer/track" => |jack: &Arc<RwLock<JackConnection>>, args| -> MixerTrack {
|
||||
let mut _gain = 0.0f64;
|
||||
let mut track = MixerTrack {
|
||||
name: String::new(),
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use PhraseCommand::*;
|
|||
use PhrasePoolCommand::*;
|
||||
|
||||
pub struct GrooveboxTui {
|
||||
_jack: Arc<RwLock<JackClient>>,
|
||||
_jack: Arc<RwLock<JackConnection>>,
|
||||
|
||||
pub player: MidiPlayer,
|
||||
pub pool: PoolModel,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ pub use self::activate::JackActivate;
|
|||
|
||||
pub mod client;
|
||||
pub(crate) use self::client::*;
|
||||
pub use self::client::JackClient;
|
||||
pub use self::client::JackConnection;
|
||||
|
||||
pub mod jack_event;
|
||||
pub(crate) use self::jack_event::*;
|
||||
|
|
@ -24,12 +24,12 @@ pub mod ports;
|
|||
pub(crate) use self::ports::*;
|
||||
pub use self::ports::RegisterPort;
|
||||
|
||||
/// Implement [TryFrom<&Arc<RwLock<JackClient>>>]: create app state from wrapped JACK handle.
|
||||
/// Implement [TryFrom<&Arc<RwLock<JackConnection>>>]: create app state from wrapped JACK handle.
|
||||
#[macro_export] macro_rules! from_jack {
|
||||
(|$jack:ident|$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)? $cb:expr) => {
|
||||
impl $(<$($L),*$($T $(: $U)?),*>)? TryFrom<&Arc<RwLock<JackClient>>> for $Struct $(<$($L),*$($T),*>)? {
|
||||
impl $(<$($L),*$($T $(: $U)?),*>)? TryFrom<&Arc<RwLock<JackConnection>>> for $Struct $(<$($L),*$($T),*>)? {
|
||||
type Error = Box<dyn std::error::Error>;
|
||||
fn try_from ($jack: &Arc<RwLock<JackClient>>) -> Usually<Self> {
|
||||
fn try_from ($jack: &Arc<RwLock<JackConnection>>) -> Usually<Self> {
|
||||
Ok($cb)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@ use crate::*;
|
|||
pub trait JackActivate: Sized {
|
||||
fn activate_with <T: Audio + 'static> (
|
||||
self,
|
||||
init: impl FnOnce(&Arc<RwLock<JackClient>>)->Usually<T>
|
||||
init: impl FnOnce(&Arc<RwLock<JackConnection>>)->Usually<T>
|
||||
)
|
||||
-> Usually<Arc<RwLock<T>>>;
|
||||
}
|
||||
|
||||
impl JackActivate for JackClient {
|
||||
impl JackActivate for JackConnection {
|
||||
fn activate_with <T: Audio + 'static> (
|
||||
self,
|
||||
init: impl FnOnce(&Arc<RwLock<JackClient>>)->Usually<T>
|
||||
init: impl FnOnce(&Arc<RwLock<JackConnection>>)->Usually<T>
|
||||
)
|
||||
-> Usually<Arc<RwLock<T>>>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ pub type DynamicAudioHandler = ClosureProcessHandler<(), BoxedAudioHandler>;
|
|||
pub type BoxedAudioHandler = Box<dyn FnMut(&Client, &ProcessScope) -> Control + Send>;
|
||||
/// Wraps [Client] or [DynamicAsyncClient] in place.
|
||||
#[derive(Debug)]
|
||||
pub enum JackClient {
|
||||
pub enum JackConnection {
|
||||
/// Before activation.
|
||||
Inactive(Client),
|
||||
/// During activation.
|
||||
|
|
@ -12,18 +12,19 @@ pub enum JackClient {
|
|||
/// After activation. Must not be dropped for JACK thread to persist.
|
||||
Active(DynamicAsyncClient),
|
||||
}
|
||||
from!(|jack: JackClient|Client = match jack {
|
||||
JackClient::Inactive(client) => client,
|
||||
JackClient::Activating => panic!("jack client still activating"),
|
||||
JackClient::Active(_) => panic!("jack client already activated"),
|
||||
from!(|jack: JackConnection|Client = match jack {
|
||||
JackConnection::Inactive(client) => client,
|
||||
JackConnection::Activating => panic!("jack client still activating"),
|
||||
JackConnection::Active(_) => panic!("jack client already activated"),
|
||||
});
|
||||
impl JackClient {
|
||||
impl JackConnection {
|
||||
pub fn new (name: &str) -> Usually<Self> {
|
||||
let (client, _) = Client::new(name, ClientOptions::NO_START_SERVER)?;
|
||||
Ok(Self::Inactive(client))
|
||||
}
|
||||
}
|
||||
impl AudioEngine for JackClient {
|
||||
impl AudioEngine for JackConnection {
|
||||
/// Return the internal [Client] handle that lets you call the JACK API.
|
||||
fn client(&self) -> &Client {
|
||||
match self {
|
||||
Self::Inactive(ref client) => client,
|
||||
|
|
@ -31,6 +32,10 @@ impl AudioEngine for JackClient {
|
|||
Self::Active(ref client) => client.as_client(),
|
||||
}
|
||||
}
|
||||
/// Bind a process callback to a `JackConnection::Inactive`,
|
||||
/// turning it into a `JackConnection::Active`. Needs work.
|
||||
/// Strange ownership situation between the callback and
|
||||
/// the host object.
|
||||
fn activate(
|
||||
self,
|
||||
mut cb: impl FnMut(&Arc<RwLock<Self>>, &Client, &ProcessScope) -> Control + Send + 'static,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ pub trait RegisterPort {
|
|||
fn connect_audio_to (&self, my_output: &Port<AudioOut>, ports: &[String]) -> Usually<()>;
|
||||
}
|
||||
|
||||
impl RegisterPort for Arc<RwLock<JackClient>> {
|
||||
impl RegisterPort for Arc<RwLock<JackConnection>> {
|
||||
fn midi_in (&self, name: &str) -> Usually<Port<MidiIn>> {
|
||||
Ok(self.read().unwrap().client().register_port(name, MidiIn::default())?)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ pub struct MidiPlayer {
|
|||
pub note_buf: Vec<u8>,
|
||||
}
|
||||
impl MidiPlayer {
|
||||
pub fn new (jack: &Arc<RwLock<JackClient>>, name: &str) -> Usually<Self> {
|
||||
pub fn new (jack: &Arc<RwLock<JackConnection>>, name: &str) -> Usually<Self> {
|
||||
Ok(Self {
|
||||
clock: ClockModel::from(jack),
|
||||
play_phrase: None,
|
||||
|
|
@ -324,7 +324,7 @@ impl HasPlayPhrase for MidiPlayer {
|
|||
///// Methods used primarily by the process callback
|
||||
//impl MIDIPlayer {
|
||||
//pub fn new (
|
||||
//jack: &Arc<RwLock<JackClient>>,
|
||||
//jack: &Arc<RwLock<JackConnection>>,
|
||||
//clock: &Arc<Clock>,
|
||||
//name: &str
|
||||
//) -> Usually<Self> {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use crate::*;
|
|||
#[derive(Debug)]
|
||||
pub struct Mixer {
|
||||
/// JACK client handle (needs to not be dropped for standalone mode to work).
|
||||
pub jack: Arc<RwLock<JackClient>>,
|
||||
pub jack: Arc<RwLock<JackConnection>>,
|
||||
pub name: String,
|
||||
pub tracks: Vec<MixerTrack>,
|
||||
pub selected_track: usize,
|
||||
|
|
@ -25,7 +25,7 @@ pub struct MixerTrack {
|
|||
audio!(|self: Mixer, _client, _scope|Control::Continue);
|
||||
|
||||
impl Mixer {
|
||||
pub fn new (jack: &Arc<RwLock<JackClient>>, name: &str) -> Usually<Self> {
|
||||
pub fn new (jack: &Arc<RwLock<JackConnection>>, name: &str) -> Usually<Self> {
|
||||
Ok(Self {
|
||||
jack: jack.clone(),
|
||||
name: name.into(),
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ pub use self::lv2::LV2Plugin;
|
|||
#[derive(Debug)]
|
||||
pub struct Plugin {
|
||||
/// JACK client handle (needs to not be dropped for standalone mode to work).
|
||||
pub jack: Arc<RwLock<JackClient>>,
|
||||
pub jack: Arc<RwLock<JackConnection>>,
|
||||
pub name: String,
|
||||
pub path: Option<String>,
|
||||
pub plugin: Option<PluginKind>,
|
||||
|
|
@ -40,7 +40,7 @@ impl Debug for PluginKind {
|
|||
}
|
||||
impl Plugin {
|
||||
pub fn new_lv2 (
|
||||
jack: &Arc<RwLock<JackClient>>,
|
||||
jack: &Arc<RwLock<JackConnection>>,
|
||||
name: &str,
|
||||
path: &str,
|
||||
) -> Usually<Self> {
|
||||
|
|
@ -131,7 +131,7 @@ audio!(|self: PluginAudio, client, scope|{
|
|||
impl Plugin {
|
||||
/// Create a plugin host device.
|
||||
pub fn new (
|
||||
jack: &Arc<RwLock<JackClient>>,
|
||||
jack: &Arc<RwLock<JackConnection>>,
|
||||
name: &str,
|
||||
) -> Usually<Self> {
|
||||
Ok(Self {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ pub use self::sample_viewer::SampleViewer;
|
|||
/// The sampler plugin plays sounds.
|
||||
#[derive(Debug)]
|
||||
pub struct Sampler {
|
||||
pub jack: Arc<RwLock<JackClient>>,
|
||||
pub jack: Arc<RwLock<JackConnection>>,
|
||||
pub name: String,
|
||||
pub mapped: [Option<Arc<RwLock<Sample>>>;128],
|
||||
pub recording: Option<(usize, Arc<RwLock<Sample>>)>,
|
||||
|
|
@ -49,7 +49,7 @@ pub struct Sampler {
|
|||
pub output_gain: f32
|
||||
}
|
||||
impl Sampler {
|
||||
pub fn new (jack: &Arc<RwLock<JackClient>>, name: &str) -> Usually<Self> {
|
||||
pub fn new (jack: &Arc<RwLock<JackConnection>>, name: &str) -> Usually<Self> {
|
||||
Ok(Self {
|
||||
midi_in: jack.midi_in(&format!("M/{name}"))?,
|
||||
audio_ins: vec![
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use PhraseCommand::*;
|
|||
use PhrasePoolCommand::*;
|
||||
/// Root view for standalone `tek_sequencer`.
|
||||
pub struct SequencerTui {
|
||||
_jack: Arc<RwLock<JackClient>>,
|
||||
_jack: Arc<RwLock<JackConnection>>,
|
||||
pub transport: bool,
|
||||
pub selectors: bool,
|
||||
pub clock: ClockModel,
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ pub struct ClockModel {
|
|||
pub chunk: Arc<AtomicUsize>,
|
||||
}
|
||||
|
||||
from!(|jack: &Arc<RwLock<JackClient>>| ClockModel = {
|
||||
from!(|jack: &Arc<RwLock<JackConnection>>| ClockModel = {
|
||||
let jack = jack.read().unwrap();
|
||||
let chunk = jack.client().buffer_size();
|
||||
let transport = jack.client().transport();
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use FocusCommand::{Next, Prev};
|
|||
use KeyCode::{Enter, Left, Right, Char};
|
||||
/// Transport clock app.
|
||||
pub struct TransportTui {
|
||||
pub jack: Arc<RwLock<JackClient>>,
|
||||
pub jack: Arc<RwLock<JackConnection>>,
|
||||
pub clock: ClockModel,
|
||||
pub size: Measure<Tui>,
|
||||
pub cursor: (usize, usize),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue