mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
jammable again - and autoconnects!
This commit is contained in:
parent
3ed9ebddd4
commit
768c2337e7
5 changed files with 98 additions and 59 deletions
|
|
@ -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::*;
|
||||
|
||||
|
|
|
|||
29
src/main.rs
29
src/main.rs
|
|
@ -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,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,39 +82,42 @@ impl Track {
|
|||
}
|
||||
}
|
||||
// Monitor and record input
|
||||
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 {
|
||||
if let Some(Some(frame)) = output.get_mut(time) {
|
||||
frame.push(bytes.into())
|
||||
} else {
|
||||
output[time] = Some(vec![bytes.into()]);
|
||||
}
|
||||
}
|
||||
if recording {
|
||||
if let Some(phrase) = phrase {
|
||||
let contains = phrase.notes.contains_key(&pulse);
|
||||
if contains {
|
||||
phrase.notes.get_mut(&pulse).unwrap().push(message.clone());
|
||||
if self.recording || self.monitoring {
|
||||
let phrase = &mut self.phrase_mut();
|
||||
for (time, event, bytes) in parse_midi_input(input) {
|
||||
match event {
|
||||
LiveEvent::Midi { message, .. } => {
|
||||
if monitoring {
|
||||
if let Some(Some(frame)) = output.get_mut(time) {
|
||||
frame.push(bytes.into())
|
||||
} else {
|
||||
phrase.notes.insert(pulse, vec![message.clone()]);
|
||||
output[time] = Some(vec![bytes.into()]);
|
||||
}
|
||||
};
|
||||
}
|
||||
match message {
|
||||
MidiMessage::NoteOn { key, .. } => {
|
||||
notes_on[key.as_int() as usize] = true;
|
||||
}
|
||||
MidiMessage::NoteOff { key, .. } => {
|
||||
notes_on[key.as_int() as usize] = false;
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
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());
|
||||
} else {
|
||||
phrase.notes.insert(pulse, vec![message.clone()]);
|
||||
}
|
||||
};
|
||||
}
|
||||
match message {
|
||||
MidiMessage::NoteOn { key, .. } => {
|
||||
notes_on[key.as_int() as usize] = true;
|
||||
}
|
||||
MidiMessage::NoteOff { key, .. } => {
|
||||
notes_on[key.as_int() as usize] = false;
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.notes_on = notes_on;
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue