define midi ins and audio outs in project

This commit is contained in:
🪞👃🪞 2024-07-12 19:20:57 +03:00
parent 58cd51dfbf
commit c4c1271c32
5 changed files with 56 additions and 35 deletions

View file

@ -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

View file

@ -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 _)

View file

@ -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::<Vec<_>>();
},
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::<Vec<_>>()
.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))
}
},

View file

@ -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<RwLock<App>>| {
run(App::from_edn(include_str!("../demos/project.edn"))?.activate(Some(|app: &Arc<RwLock<App>>| {
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::<Vec<_>>();
(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::<Vec<_>>();
(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(())
}

View file

@ -56,10 +56,10 @@ pub struct App {
/// Paths to user directories
xdg: Option<Arc<XdgApp>>,
/// Main audio outputs.
audio_outs: Vec<Arc<Port<Unowned>>>,
pub audio_outs: Vec<Arc<Port<Unowned>>>,
/// Number of frames requested by process callback
chunk_size: usize,
/// Transport model and view.
pub transport: TransportToolbar,
}