From c4c1271c32426345e952cf8de07ddf07c31c9356 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Fri, 12 Jul 2024 19:20:57 +0300 Subject: [PATCH] define midi ins and audio outs in project --- README.md | 2 +- demos/project.edn | 3 +++ src/edn.rs | 22 +++++++++++++++++ src/main.rs | 60 ++++++++++++++++++++++------------------------- src/model.rs | 4 ++-- 5 files changed, 56 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 082892f0..88cc4ecf 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ See `demos/project.edn` for the initial contents of the session. * Rust toolchain * JACK or Pipewire -## Recommended +### Recommended * MIDI controller * Samples at ~/Lab/Music/pak diff --git a/demos/project.edn b/demos/project.edn index f7554a5b..a0183597 100644 --- a/demos/project.edn +++ b/demos/project.edn @@ -1,5 +1,8 @@ (bpm 150) +(midi-in "nanoKEY Studio.*capture.*") +(audio-out "Komplete.+:playback_FL", "Komplete.+:playback_FR") + (scene { :name "Intro" } _ 0 _ _) (scene { :name "Hook" } 0 1 0 _) (scene { :name "Verse" } 1 2 1 _) diff --git a/src/edn.rs b/src/edn.rs index 6b5265d5..e56210c7 100644 --- a/src/edn.rs +++ b/src/edn.rs @@ -59,6 +59,28 @@ impl App { Some(Edn::Symbol("track")) => { Track::load_edn(self, &items[1..])?; }, + Some(Edn::Symbol("midi-in")) => { + self.midi_ins = items[1..].iter().map(|x|match x { + Edn::Str(n) => n.to_string(), + _ => panic!("unexpected midi-in") + }).collect::>(); + }, + Some(Edn::Symbol("audio-out")) => { + let client = self.client(); + self.audio_outs = items[1..].iter().map(|x|match x { + Edn::Str(n) => n.to_string(), + _ => panic!("unexpected midi-in") + }).collect::>() + .iter() + .map(|name|client + .ports(Some(name), None, PortFlags::empty()) + .get(0) + .map(|name|client.port_by_name(name))) + .flatten() + .filter_map(|x|x) + .map(Arc::new) + .collect(); + }, _ => panic!("unexpected edn: {:?}", items.get(0)) } }, diff --git a/src/main.rs b/src/main.rs index 1687eb3c..240630d3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,44 +15,40 @@ use crate::{core::*, model::*}; /// Application entrypoint. pub fn main () -> Usually<()> { - let app = App::from_edn(include_str!("../demos/project.edn"))? - .with_midi_ins(&["nanoKEY Studio.*capture.*"])? - .with_audio_outs(&["Komplete.+:playback_FL", "Komplete.+:playback_FR"])? - .activate(Some(|app: &Arc>| { + run(App::from_edn(include_str!("../demos/project.edn"))?.activate(Some(|app: &Arc>| { - let (midi_in, mut midi_outs) = { - let app = app.read().unwrap(); - let jack = app.jack.as_ref().unwrap(); - let midi_in = jack.register_port("midi-in", MidiIn)?; - let midi_outs = app.tracks.iter() - .map(|t|Some(jack.register_port(&t.name, MidiOut).unwrap())) - .collect::>(); - (midi_in, midi_outs) - }; + let (midi_in, mut midi_outs) = { + let app = app.read().unwrap(); + let jack = app.jack.as_ref().unwrap(); + let midi_in = jack.register_port("midi-in", MidiIn)?; + let midi_outs = app.tracks.iter() + .map(|t|Some(jack.register_port(&t.name, MidiOut).unwrap())) + .collect::>(); + (midi_in, midi_outs) + }; - { - let mut app = app.write().unwrap(); - let jack = app.jack.as_ref().unwrap(); - for name in app.midi_ins.iter() { - for port in jack.client().ports(Some(name), None, PortFlags::empty()).iter() { - if let Some(port) = jack.client().port_by_name(port) { - jack.client().connect_ports(&port, &midi_in)?; - } + { + let mut app = app.write().unwrap(); + let jack = app.jack.as_ref().unwrap(); + for name in app.midi_ins.iter() { + for port in jack.client().ports(Some(name), None, PortFlags::empty()).iter() { + if let Some(port) = jack.client().port_by_name(port) { + jack.client().connect_ports(&port, &midi_in)?; } } - app.midi_in = Some(Arc::new(midi_in)); - for (index, track) in app.tracks.iter_mut().enumerate() { - track.midi_out = midi_outs[index].take(); - } - for track in app.tracks.iter() { - track.connect_first_device()?; - track.connect_last_device(&app)?; - } } + app.midi_in = Some(Arc::new(midi_in)); + for (index, track) in app.tracks.iter_mut().enumerate() { + track.midi_out = midi_outs[index].take(); + } + for track in app.tracks.iter() { + track.connect_first_device()?; + track.connect_last_device(&app)?; + } + } - Ok(()) + Ok(()) - }))?; - run(app)?; + }))?)?; Ok(()) } diff --git a/src/model.rs b/src/model.rs index 38007792..e7f63bb9 100644 --- a/src/model.rs +++ b/src/model.rs @@ -56,10 +56,10 @@ pub struct App { /// Paths to user directories xdg: Option>, /// Main audio outputs. - audio_outs: Vec>>, + pub audio_outs: Vec>>, /// Number of frames requested by process callback chunk_size: usize, - + /// Transport model and view. pub transport: TransportToolbar, }