mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
refactor audio.rs
This commit is contained in:
parent
5fab1af138
commit
7f255eaea8
4 changed files with 88 additions and 68 deletions
|
|
@ -1,76 +1,14 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
impl HasJack for App { fn jack (&self) -> &Jack { &self.jack } }
|
|
||||||
audio!(
|
audio!(
|
||||||
|self: App, client, scope|{
|
|self: App, client, scope|{
|
||||||
|
|
||||||
// Start profiling cycle
|
|
||||||
let t0 = self.perf.get_t0();
|
let t0 = self.perf.get_t0();
|
||||||
|
|
||||||
// Update transport clock
|
|
||||||
self.clock().update_from_scope(scope).unwrap();
|
self.clock().update_from_scope(scope).unwrap();
|
||||||
|
let midi_in = self.collect_midi_input(scope);
|
||||||
// Collect MIDI input (TODO preallocate large buffers)
|
self.update_editor_cursor(&midi_in);
|
||||||
let midi_in = self.midi_ins.iter()
|
let result = self.render_tracks(client, scope);
|
||||||
.map(|port|port.port().iter(scope)
|
|
||||||
.map(|RawMidi { time, bytes }|(time, LiveEvent::parse(bytes)))
|
|
||||||
.collect::<Vec<_>>())
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
// Update standalone sampler
|
|
||||||
//if let Some(sampler) = self.sampler.as_mut() {
|
|
||||||
//if Control::Quit == SamplerAudio(sampler).process(client, scope) {
|
|
||||||
//return Control::Quit
|
|
||||||
//}
|
|
||||||
//for port in midi_in.iter() {
|
|
||||||
//for message in port.iter() {
|
|
||||||
//match message {
|
|
||||||
//Ok(M
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
|
|
||||||
// TODO move these to editor and sampler?:
|
|
||||||
//for port in midi_in.iter() {
|
|
||||||
//for event in port.iter() {
|
|
||||||
//match event {
|
|
||||||
//(time, Ok(LiveEvent::Midi {message, ..})) => match message {
|
|
||||||
//MidiMessage::NoteOn {ref key, ..} if let Some(editor) = self.editor.as_ref() => {
|
|
||||||
//editor.set_note_pos(key.as_int() as usize);
|
|
||||||
//},
|
|
||||||
//MidiMessage::Controller {controller, value} if let (Some(editor), Some(sampler)) = (
|
|
||||||
//self.editor.as_ref(),
|
|
||||||
//self.sampler.as_ref(),
|
|
||||||
//) => {
|
|
||||||
//// TODO: give sampler its own cursor
|
|
||||||
//if let Some(sample) = &sampler.mapped[editor.note_pos()] {
|
|
||||||
//sample.write().unwrap().handle_cc(*controller, *value)
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
//_ =>{}
|
|
||||||
//},
|
|
||||||
//_ =>{}
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
|
|
||||||
// Update track sequencers and devices
|
|
||||||
for track in self.tracks.iter_mut() {
|
|
||||||
if Control::Quit == PlayerAudio(
|
|
||||||
track.sequencer_mut(), &mut self.note_buf, &mut self.midi_buf
|
|
||||||
).process(client, scope) {
|
|
||||||
return Control::Quit
|
|
||||||
}
|
|
||||||
for device in track.devices.iter_mut() {
|
|
||||||
if Control::Quit == DeviceAudio(device).process(client, scope) {
|
|
||||||
return Control::Quit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// End profiling cycle
|
|
||||||
self.perf.update_from_jack_scope(t0, scope);
|
self.perf.update_from_jack_scope(t0, scope);
|
||||||
Control::Continue
|
result
|
||||||
};
|
};
|
||||||
|self, event|{
|
|self, event|{
|
||||||
use JackEvent::*;
|
use JackEvent::*;
|
||||||
|
|
@ -95,3 +33,60 @@ audio!(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
type CollectedMidiInput<'a> = Vec<Vec<(u32, Result<LiveEvent<'a>, MidiError>)>>;
|
||||||
|
|
||||||
|
impl App {
|
||||||
|
|
||||||
|
/// Collect MIDI input from app ports (TODO preallocate large buffers)
|
||||||
|
fn collect_midi_input <'a> (&'a self, scope: &'a ProcessScope) -> CollectedMidiInput<'a> {
|
||||||
|
self.midi_ins.iter()
|
||||||
|
.map(|port|port.port().iter(scope)
|
||||||
|
.map(|RawMidi { time, bytes }|(time, LiveEvent::parse(bytes)))
|
||||||
|
.collect::<Vec<_>>())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Update cursor in MIDI editor
|
||||||
|
fn update_editor_cursor (&self, midi_in: &CollectedMidiInput) {
|
||||||
|
if let Some(editor) = &self.editor {
|
||||||
|
let mut pitch: Option<u7> = None;
|
||||||
|
for port in midi_in.iter() {
|
||||||
|
for event in port.iter() {
|
||||||
|
if let (_, Ok(LiveEvent::Midi {message: MidiMessage::NoteOn {ref key, ..}, ..}))
|
||||||
|
= event
|
||||||
|
{
|
||||||
|
pitch = Some(key.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(pitch) = pitch {
|
||||||
|
editor.set_note_pos(pitch.as_int() as usize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run audio callbacks for every track and every device
|
||||||
|
fn render_tracks (&mut self, client: &Client, scope: &ProcessScope) -> Control {
|
||||||
|
for track in self.tracks.iter_mut() {
|
||||||
|
if Control::Quit == PlayerAudio(
|
||||||
|
track.sequencer_mut(), &mut self.note_buf, &mut self.midi_buf
|
||||||
|
).process(client, scope) {
|
||||||
|
return Control::Quit
|
||||||
|
}
|
||||||
|
for device in track.devices.iter_mut() {
|
||||||
|
if Control::Quit == DeviceAudio(device).process(client, scope) {
|
||||||
|
return Control::Quit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Control::Continue
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasJack for App {
|
||||||
|
fn jack (&self) -> &Jack {
|
||||||
|
&self.jack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ impl Track {
|
||||||
)?;
|
)?;
|
||||||
track.devices.push(Device::Sampler(Sampler::new(
|
track.devices.push(Device::Sampler(Sampler::new(
|
||||||
jack,
|
jack,
|
||||||
&"sampler",
|
&format!("{}/sampler", name.as_ref()),
|
||||||
&[PortConnect::exact(format!("{}:{}",
|
&[PortConnect::exact(format!("{}:{}",
|
||||||
jack.with_client(|c|c.name().to_string()),
|
jack.with_client(|c|c.name().to_string()),
|
||||||
track.sequencer.midi_outs[0].name()
|
track.sequencer.midi_outs[0].name()
|
||||||
|
|
|
||||||
|
|
@ -52,3 +52,27 @@ impl Sample {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
//for port in midi_in.iter() {
|
||||||
|
//for event in port.iter() {
|
||||||
|
//match event {
|
||||||
|
//(time, Ok(LiveEvent::Midi {message, ..})) => match message {
|
||||||
|
//MidiMessage::NoteOn {ref key, ..} if let Some(editor) = self.editor.as_ref() => {
|
||||||
|
//editor.set_note_pos(key.as_int() as usize);
|
||||||
|
//},
|
||||||
|
//MidiMessage::Controller {controller, value} if let (Some(editor), Some(sampler)) = (
|
||||||
|
//self.editor.as_ref(),
|
||||||
|
//self.sampler.as_ref(),
|
||||||
|
//) => {
|
||||||
|
//// TODO: give sampler its own cursor
|
||||||
|
//if let Some(sample) = &sampler.mapped[editor.note_pos()] {
|
||||||
|
//sample.write().unwrap().handle_cc(*controller, *value)
|
||||||
|
//}
|
||||||
|
//}
|
||||||
|
//_ =>{}
|
||||||
|
//},
|
||||||
|
//_ =>{}
|
||||||
|
//}
|
||||||
|
//}
|
||||||
|
//}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ pub use ::midly::{
|
||||||
Smf,
|
Smf,
|
||||||
TrackEventKind,
|
TrackEventKind,
|
||||||
MidiMessage,
|
MidiMessage,
|
||||||
|
Error as MidiError,
|
||||||
num::*,
|
num::*,
|
||||||
live::*,
|
live::*,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue