jammable again - and autoconnects!

This commit is contained in:
🪞👃🪞 2024-07-05 01:28:27 +03:00
parent 3ed9ebddd4
commit 768c2337e7
5 changed files with 98 additions and 59 deletions

View file

@ -63,9 +63,32 @@ const KEYMAP: &'static [KeyBinding<App>] = keymap!(App {
}
}],
[F(1), NONE, "toggle_help", "toggle help", |_: &mut App| {Ok(true)}],
[Char('r'), NONE, "toggle_record", "toggle recording", |_: &mut App| {Ok(true)}],
[Char('d'), NONE, "toggle_overdub", "toggle overdub", |_: &mut App| {Ok(true)}],
[Char('m'), NONE, "toggle_monitor", "toggle input monitoring", |_: &mut App| {Ok(true)}],
[Char('r'), NONE, "toggle_record", "toggle recording", |app: &mut App| {
app.track_mut().map(|t|t.1.toggle_record());
Ok(true)
}],
[Char('d'), NONE, "toggle_overdub", "toggle overdub", |app: &mut App| {
app.track_mut().map(|t|t.1.toggle_overdub());
Ok(true)
}],
[Char('m'), NONE, "toggle_monitor", "toggle input monitoring", |app: &mut App| {
app.track_mut().map(|t|t.1.toggle_monitor());
Ok(true)
}],
//fn toggle_record (s: &mut Launcher) -> Usually<bool> {
//s.sequencer_mut().map(|s|s.recording = !s.recording);
//Ok(true)
//}
//fn toggle_overdub (s: &mut Launcher) -> Usually<bool> {
//s.sequencer_mut().map(|s|s.overdub = !s.overdub);
//Ok(true)
//}
//fn toggle_monitor (s: &mut Launcher) -> Usually<bool> {
//s.sequencer_mut().map(|s|s.monitoring = !s.monitoring);
//Ok(true)
//}
[Up, NONE, "cursor_up", "move cursor up", |app: &mut App| {
if app.entered {
match app.section {
@ -152,7 +175,7 @@ const KEYMAP: &'static [KeyBinding<App>] = keymap!(App {
[Char('d'), CONTROL, "duplicate", "duplicate scene or track", duplicate],
[Enter, NONE, "activate", "activate item at cursor", enter],
[Esc, NONE, "escape", "unfocus", escape],
[Char('r'), CONTROL, "rename", "rename current element", rename],
//[Char('r'), CONTROL, "rename", "rename current element", rename],
// [Char('='), NONE, "zoom_in", "Zoom in", zoom_in],
// [Char('-'), NONE, "zoom_out", "Zoom out", zoom_out],
// [Char('a'), NONE, "note_add", "Add note", note_add],
@ -347,20 +370,6 @@ fn duplicate (_: &mut App) -> Usually<bool> { Ok(true) }
fn rename (_: &mut App) -> Usually<bool> { Ok(true) }
//fn toggle_record (s: &mut Launcher) -> Usually<bool> {
//s.sequencer_mut().map(|s|s.recording = !s.recording);
//Ok(true)
//}
//fn toggle_overdub (s: &mut Launcher) -> Usually<bool> {
//s.sequencer_mut().map(|s|s.overdub = !s.overdub);
//Ok(true)
//}
//fn toggle_monitor (s: &mut Launcher) -> Usually<bool> {
//s.sequencer_mut().map(|s|s.monitoring = !s.monitoring);
//Ok(true)
//}
//use crate::{core::*, model::*};
//use super::focus::*;

View file

@ -33,6 +33,20 @@ pub fn main () -> Usually<()> {
state.playing = Some(TransportState::Stopped);
state.midi_in = Some(client.register_port("midi-in", MidiIn)?);
let _ = ["nanoKEY Studio.*capture.*"]
.iter()
.map(|name|client
.ports(Some(name), None, PortFlags::empty())
.iter()
.map(|name|{
if let Some(port) = client.port_by_name(name) {
client.connect_ports(&port, &state.midi_in.as_ref().unwrap())?;
}
Ok(())
})
.collect::<Usually<()>>())
.collect::<Usually<()>>()?;
let timebase = &state.timebase;
let ppq = timebase.ppq() as usize;
state.track_cursor = 1;
@ -54,7 +68,9 @@ pub fn main () -> Usually<()> {
state.add_track_with_cb(Some("Drums"), |_, track|{
track.add_device_with_cb(Sampler::new("Sampler", Some(BTreeMap::from([
sample!(36, "Kick", "/home/user/Lab/Music/pak/kik.wav"),
sample!(34, "808", "/home/user/Lab/Music/pak/808.wav"),
sample!(35, "Kick1", "/home/user/Lab/Music/pak/kik.wav"),
sample!(36, "Kick2", "/home/user/Lab/Music/pak/kik2.wav"),
sample!(40, "Snare", "/home/user/Lab/Music/pak/sna.wav"),
sample!(44, "Hihat", "/home/user/Lab/Music/pak/chh.wav"),
])))?, |track, device|{
@ -89,13 +105,13 @@ pub fn main () -> Usually<()> {
00 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
04 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() },
08 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
10 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
10 * ppq/4 => MidiMessage::NoteOn { key: 35.into(), vel: 100.into() },
12 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() },
}));
track.add_phrase("Garage", ppq * 4, Some(phrase! {
00 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
00 * ppq/4 => MidiMessage::NoteOn { key: 35.into(), vel: 100.into() },
04 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() },
11 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
11 * ppq/4 => MidiMessage::NoteOn { key: 35.into(), vel: 100.into() },
12 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() },
}));
Ok(())
@ -105,7 +121,8 @@ pub fn main () -> Usually<()> {
track.add_device_with_cb(Plugin::lv2(
"Odin2",
"file:///home/user/.lv2/Odin2.lv2"
)?, |_, device|{
)?, |track, device|{
device.connect_midi_in(0, &track.midi_out.clone_unowned())?;
if let Some(Some(left)) = outputs.get(0) {
device.connect_audio_out(0, left)?;
}
@ -208,7 +225,7 @@ process!(App |self, _client, scope| {
&self.timebase,
self.playing,
&scope,
frame,
self.playhead,
frames,
panic,
);

View file

@ -70,6 +70,7 @@ impl Sampler {
// dropping voices that have reached their ends.
let mut voices = vec![];
std::mem::swap(&mut voices, &mut self.voices);
let gain = 0.5;
loop {
if voices.len() < 1 {
break
@ -79,7 +80,7 @@ impl Sampler {
for (i, channel) in chunk.iter().enumerate() {
let buffer = &mut mixed[i % channel_count];
for (i, sample) in channel.iter().enumerate() {
buffer[i] += sample;
buffer[i] += sample * gain;
}
}
self.voices.push(voice);

View file

@ -61,7 +61,7 @@ impl Track {
frames: usize,
panic: bool,
) {
// Need to be borrowed outside the conditional
// Need to be borrowed outside the conditionals?
let recording = self.recording;
let monitoring = self.monitoring;
// Output buffer
@ -82,9 +82,9 @@ impl Track {
}
}
// Monitor and record input
if self.recording || self.monitoring {
let phrase = &mut self.phrase_mut();
for (time, event, bytes) in parse_midi_input(input) {
let pulse = timebase.frames_pulses((frame0 + time) as f64) as usize;
match event {
LiveEvent::Midi { message, .. } => {
if monitoring {
@ -96,6 +96,8 @@ impl Track {
}
if recording {
if let Some(phrase) = phrase {
let pulse = timebase.frames_pulses((frame0 + time) as f64) as usize;
let pulse = pulse % phrase.length;
let contains = phrase.notes.contains_key(&pulse);
if contains {
phrase.notes.get_mut(&pulse).unwrap().push(message.clone());
@ -117,6 +119,7 @@ impl Track {
_ => {}
}
}
}
self.notes_on = notes_on;
write_midi_output(&mut self.midi_out.writer(scope), &output, frames);
}
@ -171,4 +174,13 @@ impl Track {
let index = self.phrases.len() - 1;
&mut self.phrases[index]
}
pub fn toggle_monitor (&mut self) {
self.monitoring = !self.monitoring;
}
pub fn toggle_record (&mut self) {
self.recording = !self.recording;
}
pub fn toggle_overdub (&mut self) {
self.overdub = !self.overdub;
}
}

View file

@ -21,9 +21,9 @@ render!(App |self, buf, area| {
y = y + TransportView {
timebase: &self.timebase,
playing: *self.playing.as_ref().unwrap_or(&TransportState::Stopped),
record: false,
overdub: false,
monitor: false,
monitor: self.track().map(|t|t.1.monitoring).unwrap_or(false),
record: self.track().map(|t|t.1.recording).unwrap_or(false),
overdub: self.track().map(|t|t.1.overdub).unwrap_or(false),
frame: self.playhead,
}.render(buf, area)?.height;