mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
wip: unpetrify, tryna dodge 4000
This commit is contained in:
parent
ea529b7734
commit
b4fdddc0aa
7 changed files with 161 additions and 78 deletions
|
|
@ -31,8 +31,8 @@ pub const KEYMAP: &'static [KeyBinding<Launcher>] = keymap!(Launcher {
|
|||
[Char('r'), NONE, "record_toggle", "toggle recording", record_toggle],
|
||||
[Char('d'), NONE, "overdub_toggle", "toggle overdub", overdub_toggle],
|
||||
[Char('m'), NONE, "monitor_toggle", "toggle input monitoring", monitor_toggle],
|
||||
[Char('r'), CONTROL, "rename", "rename current element", rename],
|
||||
[Char('t'), CONTROL, "add_track", "add a new track", add_track],
|
||||
//[Char('r'), CONTROL, "rename", "rename current element", rename],
|
||||
//[Char('t'), CONTROL, "add_track", "add a new track", add_track],
|
||||
//[Char(' '), SHIFT, "play_start", "play from start", play_start],
|
||||
});
|
||||
pub const KEYMAP_TRACKS: &'static [KeyBinding<Launcher>] = keymap!(Launcher {
|
||||
|
|
@ -105,16 +105,16 @@ fn activate (_: &mut Launcher) -> Usually<bool> {
|
|||
Ok(true)
|
||||
}
|
||||
|
||||
fn rename (_: &mut Launcher) -> Usually<bool> {
|
||||
Ok(true)
|
||||
}
|
||||
//fn rename (_: &mut Launcher) -> Usually<bool> {
|
||||
//Ok(true)
|
||||
//}
|
||||
|
||||
fn add_track (state: &mut Launcher) -> Usually<bool> {
|
||||
let name = format!("Track {}", state.tracks.len() + 1);
|
||||
state.tracks.push(Track::new(&name, &state.timebase, None, None)?);
|
||||
state.cursor.0 = state.tracks.len();
|
||||
Ok(true)
|
||||
}
|
||||
//fn add_track (state: &mut Launcher) -> Usually<bool> {
|
||||
//let name = format!("Track {}", state.tracks.len() + 1);
|
||||
//state.tracks.push(Track::new(&name, &state.timebase, None, None)?);
|
||||
//state.cursor.0 = state.tracks.len();
|
||||
//Ok(true)
|
||||
//}
|
||||
|
||||
fn delete_track (state: &mut Launcher) -> Usually<bool> {
|
||||
if state.tracks.len() > 0 && state.cursor.0 >= 1 {
|
||||
|
|
|
|||
|
|
@ -25,27 +25,8 @@ pub const KEYMAP: &'static [KeyBinding<Sequencer>] = keymap!(Sequencer {
|
|||
[Char('s'), NONE, "stop_and_rewind", "Stop and rewind", stop_and_rewind],
|
||||
[Char('q'), NONE, "quantize_next", "Next quantize value", quantize_next],
|
||||
[Char('Q'), SHIFT, "quantize_prev", "Previous quantize value", quantize_prev],
|
||||
[Char('n'), NONE, "note_axis", "Focus note axis", nop],
|
||||
[Char('t'), NONE, "time_axis", "Focus time axis", nop],
|
||||
[Char('v'), NONE, "variations", "Focus variation selector", nop],
|
||||
[Char('s'), SHIFT, "sync", "Focus sync selector", nop],
|
||||
[Char('1'), NONE, "seq_1", "Phrase 1", focus_seq(0)],
|
||||
[Char('2'), NONE, "seq_2", "Phrase 2", focus_seq(1)],
|
||||
[Char('3'), NONE, "seq_3", "Phrase 3", focus_seq(2)],
|
||||
[Char('4'), NONE, "seq_4", "Phrase 4", focus_seq(3)],
|
||||
[Char('5'), NONE, "seq_5", "Phrase 5", focus_seq(4)],
|
||||
[Char('6'), NONE, "seq_6", "Phrase 6", focus_seq(5)],
|
||||
[Char('7'), NONE, "seq_7", "Phrase 7", focus_seq(6)],
|
||||
[Char('8'), NONE, "seq_8", "Phrase 8", focus_seq(7)],
|
||||
});
|
||||
|
||||
const fn focus_seq (i: usize) -> impl Fn(&mut Sequencer)->Usually<bool> {
|
||||
move |s: &mut Sequencer| {
|
||||
s.sequence = Some(i);
|
||||
Ok(true)
|
||||
}
|
||||
}
|
||||
|
||||
fn nop (_: &mut Sequencer) -> Usually<bool> {
|
||||
Ok(false)
|
||||
}
|
||||
|
|
|
|||
0
src/core/layout.rs
Normal file
0
src/core/layout.rs
Normal file
175
src/main.rs
175
src/main.rs
|
|
@ -17,6 +17,15 @@ use crate::core::*;
|
|||
use crate::model::*;
|
||||
use crate::view::*;
|
||||
|
||||
macro_rules! phrase {
|
||||
($($t:expr => $msg:expr),* $(,)?) => {{
|
||||
let mut phrase = BTreeMap::new();
|
||||
$(phrase.insert($t, vec![]);)*
|
||||
$(phrase.get_mut(&$t).unwrap().push($msg);)*
|
||||
phrase
|
||||
}}
|
||||
}
|
||||
|
||||
pub fn main () -> Usually<()> {
|
||||
App::default().run(Some(|app: Arc<Mutex<App>>|{
|
||||
let mut state = app.lock().unwrap();
|
||||
|
|
@ -26,20 +35,50 @@ pub fn main () -> Usually<()> {
|
|||
state.modal = Some(Box::new(crate::config::SetupModal(Some(xdg.clone()))));
|
||||
}
|
||||
state.scenes = vec![
|
||||
Scene::new("Intro", vec![None, None, None, None]),
|
||||
Scene::new("Intro", vec![Some(0), Some(0), None, None]),
|
||||
];
|
||||
let jack = jack_run("tek", &app)?;
|
||||
let timebase = &state.timebase;
|
||||
let ppq = timebase.ppq() as usize;
|
||||
state.tracks = vec![
|
||||
Track::new("Drums", &state.timebase, Some(vec![
|
||||
|
||||
Track::new("Drums", &jack.as_client(), &timebase, Some(vec![
|
||||
|
||||
Sampler::new("Sampler", Some(BTreeMap::from([
|
||||
sample!(36, "Kick", "/home/user/Lab/Music/pak/kik.wav"),
|
||||
sample!(40, "Snare", "/home/user/Lab/Music/pak/sna.wav"),
|
||||
sample!(44, "Hihat", "/home/user/Lab/Music/pak/chh.wav"),
|
||||
])))?.boxed(),
|
||||
|
||||
Plugin::lv2(
|
||||
"Panagement",
|
||||
"file:///home/user/.lv2/Auburn Sounds Panagement 2.lv2"
|
||||
)?.boxed(),
|
||||
|
||||
]), Some(vec![
|
||||
Phrase::new("4 kicks", state.timebase.ppq() as usize * 4, None),
|
||||
Phrase::new("4 kicks", ppq * 4, Some(phrase! {
|
||||
00 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
|
||||
04 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
|
||||
08 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
|
||||
12 * ppq/4 => MidiMessage::NoteOn { key: 36.into(), vel: 100.into() },
|
||||
})),
|
||||
]))?,
|
||||
|
||||
Track::new("Bass", &jack.as_client(), &timebase, Some(vec![
|
||||
]), Some(vec![
|
||||
Phrase::new("Offbeat", ppq * 4, Some(phrase! {
|
||||
00 * ppq/4 => MidiMessage::NoteOff { key: 40.into(), vel: 100.into() },
|
||||
02 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() },
|
||||
04 * ppq/4 => MidiMessage::NoteOff { key: 40.into(), vel: 100.into() },
|
||||
06 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() },
|
||||
08 * ppq/4 => MidiMessage::NoteOff { key: 40.into(), vel: 100.into() },
|
||||
10 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() },
|
||||
12 * ppq/4 => MidiMessage::NoteOff { key: 40.into(), vel: 100.into() },
|
||||
14 * ppq/4 => MidiMessage::NoteOn { key: 40.into(), vel: 100.into() },
|
||||
})),
|
||||
]))?,
|
||||
];
|
||||
state.jack = Some(jack_run("tek", &app)?);
|
||||
state.jack = Some(jack);
|
||||
Ok(())
|
||||
}))
|
||||
}
|
||||
|
|
@ -48,13 +87,15 @@ pub fn main () -> Usually<()> {
|
|||
pub struct App {
|
||||
pub xdg: Option<Arc<XdgApp>>,
|
||||
pub jack: Option<DynamicAsyncClient>,
|
||||
pub phrases: Vec<Phrase>,
|
||||
pub scene: usize,
|
||||
pub scenes: Vec<Scene>,
|
||||
pub track_cursor: usize,
|
||||
pub tracks: Vec<Track>,
|
||||
pub frame: usize,
|
||||
pub scene: Vec<usize>,
|
||||
pub timebase: Arc<Timebase>,
|
||||
pub modal: Option<Box<dyn Component>>,
|
||||
pub section: usize,
|
||||
pub entered: bool,
|
||||
}
|
||||
|
||||
process!(App);
|
||||
|
|
@ -75,23 +116,26 @@ render!(App |self, buf, area| {
|
|||
buf,
|
||||
area: Rect { x, y, width, height: height / 3 },
|
||||
name: "",
|
||||
focused: true,
|
||||
focused: self.section == 0,
|
||||
scenes: &self.scenes,
|
||||
tracks: &self.tracks,
|
||||
cursor: &(0, 0)
|
||||
cursor: &(self.track_cursor, self.scene + 1)
|
||||
}.draw()?.height;
|
||||
|
||||
y = y + ChainView {
|
||||
focused: true,
|
||||
chain: Some(&self.tracks[0].chain),
|
||||
}.render(buf, Rect { x, y, width, height: height / 3 })?.height;
|
||||
if self.track_cursor > 0 {
|
||||
let track = self.tracks.get(self.track_cursor - 1);
|
||||
y = y + ChainView {
|
||||
focused: self.section == 1,
|
||||
chain: track.map(|t|&t.chain),
|
||||
}.render(buf, Rect { x, y, width, height: height / 3 })?.height;
|
||||
|
||||
y = y + SequencerView {
|
||||
focused: true,
|
||||
ppq: self.timebase.ppq() as usize,
|
||||
track: Some(&self.tracks[0]),
|
||||
phrase: Some(&self.tracks[0].sequencer.phrases[0]),
|
||||
}.render(buf, Rect { x, y, width, height })?.height;
|
||||
y = y + SequencerView {
|
||||
focused: self.section == 2,
|
||||
ppq: self.timebase.ppq() as usize,
|
||||
track: track,
|
||||
phrase: track.map(|t|&t.sequencer.phrases[0]),
|
||||
}.render(buf, Rect { x, y, width, height })?.height;
|
||||
}
|
||||
|
||||
if let Some(ref modal) = self.modal {
|
||||
for cell in buf.content.iter_mut() {
|
||||
|
|
@ -134,27 +178,90 @@ handle!(App |self, e| {
|
|||
}))
|
||||
});
|
||||
|
||||
fn increment (_: &mut App) -> Usually<bool> { Ok(true) }
|
||||
fn decrement (_: &mut App) -> Usually<bool> { Ok(true) }
|
||||
fn delete (_: &mut App) -> Usually<bool> { Ok(true) }
|
||||
fn focus_next (app: &mut App) -> Usually<bool> {
|
||||
if app.section >= 2 {
|
||||
app.section = 0;
|
||||
} else {
|
||||
app.section = app.section + 1;
|
||||
}
|
||||
Ok(true)
|
||||
}
|
||||
fn focus_prev (app: &mut App) -> Usually<bool> {
|
||||
if app.section == 0 {
|
||||
app.section = 2;
|
||||
} else {
|
||||
app.section = app.section - 1;
|
||||
}
|
||||
Ok(true)
|
||||
}
|
||||
fn cursor_up (app: &mut App) -> Usually<bool> {
|
||||
focus_prev(app)
|
||||
}
|
||||
fn cursor_down (app: &mut App) -> Usually<bool> {
|
||||
focus_next(app)
|
||||
}
|
||||
fn cursor_left (app: &mut App) -> Usually<bool> {
|
||||
match app.section {
|
||||
0 => {
|
||||
app.track_cursor = if app.track_cursor == 0 {
|
||||
app.tracks.len()
|
||||
} else {
|
||||
app.track_cursor
|
||||
} - 1;
|
||||
Ok(true)
|
||||
}
|
||||
_ => Ok(false)
|
||||
}
|
||||
}
|
||||
fn cursor_right (app: &mut App) -> Usually<bool> {
|
||||
match app.section {
|
||||
0 => {
|
||||
app.track_cursor = if app.track_cursor >= app.tracks.len() {
|
||||
0
|
||||
} else {
|
||||
app.track_cursor + 1
|
||||
};
|
||||
Ok(true)
|
||||
},
|
||||
_ => Ok(false)
|
||||
}
|
||||
}
|
||||
fn increment (app: &mut App) -> Usually<bool> {
|
||||
match app.section {
|
||||
0 => clip_next(app),
|
||||
_ => Ok(false)
|
||||
}
|
||||
}
|
||||
fn decrement (app: &mut App) -> Usually<bool> {
|
||||
match app.section {
|
||||
0 => clip_prev(app),
|
||||
_ => Ok(false)
|
||||
}
|
||||
}
|
||||
fn delete (app: &mut App) -> Usually<bool> {
|
||||
match app.section {
|
||||
0 => delete_track(app),
|
||||
_ => Ok(false)
|
||||
}
|
||||
}
|
||||
fn duplicate (_: &mut App) -> Usually<bool> { Ok(true) }
|
||||
fn activate (_: &mut App) -> Usually<bool> { Ok(true) }
|
||||
fn rename (_: &mut App) -> Usually<bool> { Ok(true) }
|
||||
fn add_track (app: &mut App) -> Usually<bool> {
|
||||
let name = format!("Track {}", app.tracks.len() + 1);
|
||||
app.tracks.push(Track::new(&name, &app.timebase, None, None)?);
|
||||
app.tracks.push(Track::new(&name, app.jack.as_ref().unwrap().as_client(), &app.timebase, None, None)?);
|
||||
app.track_cursor = app.tracks.len() - 1;
|
||||
Ok(true)
|
||||
}
|
||||
fn delete_track (_: &mut App) -> Usually<bool> {
|
||||
Ok(true)
|
||||
fn delete_track (app: &mut App) -> Usually<bool> {
|
||||
if app.tracks.len() > 0 {
|
||||
app.tracks.remove(app.track_cursor);
|
||||
app.track_cursor = app.track_cursor.saturating_sub(1);
|
||||
return Ok(true)
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
fn cursor_up (_: &mut App) -> Usually<bool> { Ok(true) }
|
||||
fn cursor_down (_: &mut App) -> Usually<bool> { Ok(true) }
|
||||
fn cursor_left (_: &mut App) -> Usually<bool> { Ok(true) }
|
||||
fn cursor_right (_: &mut App) -> Usually<bool> { Ok(true) }
|
||||
fn toggle_help (_: &mut App) -> Usually<bool> { Ok(true) }
|
||||
fn focus_next (_: &mut App) -> Usually<bool> { Ok(true) }
|
||||
fn focus_prev (_: &mut App) -> Usually<bool> { Ok(true) }
|
||||
fn clip_next (_: &mut App) -> Usually<bool> { Ok(true) }
|
||||
fn clip_prev (_: &mut App) -> Usually<bool> { Ok(true) }
|
||||
fn play_toggle (_: &mut App) -> Usually<bool> { Ok(true) }
|
||||
|
|
@ -175,14 +282,6 @@ fn monitor_toggle (_: &mut App) -> Usually<bool> { Ok(true) }
|
|||
//( $t1 * ppq / 4, vec![ $($msg),* ] )
|
||||
//}
|
||||
//}
|
||||
//macro_rules! phrase {
|
||||
//($($t:expr => $msg:expr),* $(,)?) => {{
|
||||
//let mut phrase = BTreeMap::new();
|
||||
//$(phrase.insert($t, vec![]);)*
|
||||
//$(phrase.get_mut(&$t).unwrap().push($msg);)*
|
||||
//phrase
|
||||
//}}
|
||||
//}
|
||||
//Launcher::new("Launcher#0", &timebase,
|
||||
//Some(vec![
|
||||
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ impl Launcher {
|
|||
cursor: (2, 2),
|
||||
current_frame: 0,
|
||||
scenes: scenes.unwrap_or_else(||vec![Scene::new(&"Scene 1", &[None])]),
|
||||
tracks: if let Some(tracks) = tracks { tracks } else { vec![
|
||||
tracks: vec![]/*if let Some(tracks) = tracks { tracks } else { vec![
|
||||
Track::new("Track 1", &timebase, None, Some(vec![
|
||||
Phrase::new("MIDI Clip 1", ppq * 4, Some(BTreeMap::from([
|
||||
( ppq * 0, vec![MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }] ),
|
||||
|
|
@ -70,7 +70,7 @@ impl Launcher {
|
|||
( ppq * 3, vec![MidiMessage::NoteOn { key: 36.into(), vel: 100.into() }] ),
|
||||
])))
|
||||
]))?,
|
||||
] },
|
||||
] }*/,
|
||||
show_help: true,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,17 +5,20 @@ pub struct Track {
|
|||
pub name: String,
|
||||
pub sequencer: Sequencer,
|
||||
pub chain: Chain,
|
||||
pub midi_out: Port<MidiOut>,
|
||||
}
|
||||
|
||||
impl Track {
|
||||
pub fn new (
|
||||
name: &str,
|
||||
tempo: &Arc<Timebase>,
|
||||
devices: Option<Vec<Box<dyn Device>>>,
|
||||
phrases: Option<Vec<Phrase>>,
|
||||
name: &str,
|
||||
jack: &Client,
|
||||
timebase: &Arc<Timebase>,
|
||||
devices: Option<Vec<Box<dyn Device>>>,
|
||||
phrases: Option<Vec<Phrase>>,
|
||||
) -> Usually<Self> {
|
||||
let sequencer = Sequencer::new(&name, tempo, phrases)?;
|
||||
let chain = Chain::new(&name, devices)?;
|
||||
let sequencer = Sequencer::new(&name, timebase, phrases)?;
|
||||
let chain = Chain::new(&name, devices)?;
|
||||
let midi_out = jack.register_port(name, MidiOut)?;
|
||||
//let (client, _status) = Client::new("init", ClientOptions::NO_START_SERVER)?;
|
||||
//{
|
||||
//if let (Some(output), Some(input)) = (
|
||||
|
|
@ -33,7 +36,7 @@ impl Track {
|
|||
//client.connect_ports_by_name(&output, &input)?;
|
||||
//}
|
||||
//}
|
||||
Ok(Self { name: name.to_string(), sequencer, chain })
|
||||
Ok(Self { name: name.to_string(), sequencer, chain, midi_out })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ pub fn draw_as_row (
|
|||
state: &Chain, buf: &mut Buffer, area: Rect, style: Option<Style>
|
||||
) -> Usually<(Rect, Vec<Rect>)> {
|
||||
let Rect { mut x, y, width, height } = area;
|
||||
let mut h = 0u16;
|
||||
let mut h = 3u16;
|
||||
let mut frames = vec![];
|
||||
for (i, device) in state.items.iter().enumerate() {
|
||||
let x2 = 0u16;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue