mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
wip: long awaited fixes to main sequencer
This commit is contained in:
parent
2837ffff4a
commit
78e5469b32
17 changed files with 391 additions and 563 deletions
|
|
@ -1,6 +1,13 @@
|
|||
use crate::core::*;
|
||||
use crate::layout::*;
|
||||
|
||||
pub fn draw_timer (buf: &mut Buffer, x: u16, y: u16, timebase: &Arc<Timebase>, frame: usize) {
|
||||
let tick = (frame as f64 / timebase.frames_per_tick()) as usize;
|
||||
let (beats, ticks) = (tick / timebase.ppq(), tick % timebase.ppq());
|
||||
let (bars, beats) = (beats / 4, beats % 4);
|
||||
let timer = format!("{}.{}.{ticks:02}", bars + 1, beats + 1);
|
||||
timer.blit(buf, x - timer.len() as u16, y, Some(Style::default().not_dim()));
|
||||
}
|
||||
pub fn draw_play_stop (buf: &mut Buffer, x: u16, y: u16, state: &TransportState) {
|
||||
let style = Style::default().gray();
|
||||
match state {
|
||||
|
|
@ -34,10 +41,25 @@ pub fn draw_mon (buf: &mut Buffer, x: u16, y: u16, on: bool) {
|
|||
Style::default().bold().dim()
|
||||
}))
|
||||
}
|
||||
pub fn draw_bpm (buf: &mut Buffer, x: u16, y: u16, bpm: usize) {
|
||||
let style = Style::default().not_dim();
|
||||
"BPM"
|
||||
.blit(buf, x, y, Some(style));
|
||||
format!("{:03}.{:03}", bpm / 1000, bpm % 1000)
|
||||
.blit(buf, x + 4, y, Some(style.bold()));
|
||||
"SYNC"
|
||||
.blit(buf, x + 13, y, Some(style));
|
||||
"4/4"
|
||||
.blit(buf, x + 18, y, Some(style.bold()));
|
||||
"QUANT"
|
||||
.blit(buf, x + 23, y, Some(style));
|
||||
"1/16"
|
||||
.blit(buf, x + 29, y, Some(style.bold()));
|
||||
}
|
||||
|
||||
pub struct Transport {
|
||||
name: String,
|
||||
/// Holds info about tempo
|
||||
/// Holds info about bpm
|
||||
timebase: Arc<Timebase>,
|
||||
|
||||
transport: ::jack::Transport,
|
||||
|
|
@ -51,7 +73,7 @@ impl Transport {
|
|||
name: name.into(),
|
||||
timebase: Arc::new(Timebase {
|
||||
rate: AtomicUsize::new(client.sample_rate()),
|
||||
tempo: AtomicUsize::new(113000),
|
||||
bpm: AtomicUsize::new(113000),
|
||||
ppq: AtomicUsize::new(96),
|
||||
}),
|
||||
transport
|
||||
|
|
@ -86,6 +108,10 @@ pub fn process (_: &mut Transport, _: &Client, _: &ProcessScope) -> Control {
|
|||
Control::Continue
|
||||
}
|
||||
|
||||
pub fn handle (_: &mut Transport, _: &AppEvent) -> Usually<bool> {
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
pub fn render (state: &Transport, buf: &mut Buffer, mut area: Rect)
|
||||
-> Usually<Rect>
|
||||
{
|
||||
|
|
@ -102,8 +128,8 @@ pub fn render (state: &Transport, buf: &mut Buffer, mut area: Rect)
|
|||
"REC",
|
||||
"DUB",
|
||||
&format!("BPM {:03}.{:03}",
|
||||
state.timebase.tempo() / 1000,
|
||||
state.timebase.tempo() % 1000,
|
||||
state.timebase.bpm() / 1000,
|
||||
state.timebase.bpm() % 1000,
|
||||
),
|
||||
"0.0+00",
|
||||
"0:00.000",
|
||||
|
|
@ -114,163 +140,4 @@ pub fn render (state: &Transport, buf: &mut Buffer, mut area: Rect)
|
|||
x = x + 2;
|
||||
}
|
||||
Ok(area)
|
||||
//buf.set_string(area.x, area.y + 5, "Witty Gerbil - Sha Na Na", label.bold());
|
||||
//&format!(" │ 00:00.00 / 00:00.00"), style);
|
||||
//draw_leaf(buf, area, 1, 0, "REC");
|
||||
//draw_leaf(buf, area, 1, 5, "DUB");
|
||||
//draw_leaf(buf, area, 1, 10, "STOP");
|
||||
//draw_leaf(buf, area, 1, 16, "PLAY/PAUSE");
|
||||
//draw_leaf(buf, area, 1, 28, "START");
|
||||
//draw_leaf(buf, area, 1, 35, "Project: Witty Gerbil - Sha Na Na ");
|
||||
//draw_leaf(buf, area, 3, 0, &format!("BPM {:03}.{:03}",
|
||||
//state.bpm as u64,
|
||||
//((state.bpm % 1.0) * 1000.0) as u64
|
||||
//));
|
||||
//let position = state.transport.as_ref().map(|t|t.query());
|
||||
//if let Some(Ok(position)) = position {
|
||||
//let rate = position.pos.frame_rate().unwrap();
|
||||
//let frame = position.pos.frame();
|
||||
//let second = (frame as f64) / (rate as f64);
|
||||
//let minute = second / 60f64;
|
||||
//let bpm = 120f64;
|
||||
//let div = 4;
|
||||
//let beats = minute * bpm;
|
||||
//let bars = beats as u32 / div as u32;
|
||||
//let beat = beats as u32 % div as u32 + 1;
|
||||
//let beat_sub = beats % 1.0;
|
||||
////buf.set_string(
|
||||
////area.x - 18, area.y + area.height,
|
||||
////format!("BBT {bars:04}:{beat:02}.{:02}", (beat_sub * 16.0) as u32),
|
||||
////Style::default()
|
||||
////);
|
||||
//draw_leaf(buf, area, 3, 13, &format!("BBT {bars:04}:{beat:02}.{:02}",
|
||||
//(beat_sub * 16.0) as u32
|
||||
//));
|
||||
//let time = frame as f64 / rate as f64;
|
||||
//let seconds = time % 60.0;
|
||||
//let msec = seconds % 1.0;
|
||||
//let minutes = (time / 60.0) % 60.0;
|
||||
//let hours = time / 3600.0;
|
||||
//draw_leaf(buf, area, 3, 29, &format!("Time {:02}:{:02}:{:02}.{:03}",
|
||||
//hours as u64,
|
||||
//minutes as u64,
|
||||
//seconds as u64,
|
||||
//(msec * 1000.0) as u64
|
||||
//));
|
||||
//draw_leaf(buf, area, 3, 48, &format!("Rate {:>6}Hz", rate));
|
||||
//draw_leaf(buf, area, 3, 63, &format!("Frame {:>10}", frame));
|
||||
//}
|
||||
//let bbt = position.pos.bbt().map(|mut bbt|*bbt
|
||||
//.with_bpm(state.bpm)
|
||||
//.with_timesig(state.timesig.0, state.timesig.1));
|
||||
//.unwrap();
|
||||
//Line::from("Project:").render(area, buf);
|
||||
//if let Ok(position) = state.transport.query() {
|
||||
//let frame = position.pos.frame();
|
||||
//let rate = position.pos.frame_rate();
|
||||
//let bbt = position.pos.bbt().map(|mut bbt|*bbt
|
||||
//.with_bpm(state.bpm)
|
||||
//.with_timesig(state.timesig.0, state.timesig.1));
|
||||
//Line::from("Frame:").render(area.clone().offset(Offset { x: 0, y: 1 }), buf);
|
||||
//Line::from(format!("{frame}")).render(area.clone().offset(Offset { x: 0, y: 2 }), buf);
|
||||
//Line::from("Rate:").render(area.clone().offset(Offset { x: 10, y: 1 }), buf);
|
||||
//Line::from(match rate {
|
||||
//Some(rate) => format!("{rate}Hz"),
|
||||
//None => String::from("(none)"),
|
||||
//}).render(area.clone().offset(Offset { x: 10, y: 2 }), buf);
|
||||
//Line::from("Time:").render(area.clone().offset(Offset { x: 20, y: 1 }), buf);
|
||||
//Line::from(match rate {
|
||||
//Some(rate) => format!("{:.03}", frame as f64 / rate as f64),
|
||||
//None => String::from("(none)")
|
||||
//}).render(area.clone().offset(Offset { x: 20, y: 2 }), buf);
|
||||
//Line::from("BPM:").render(area.clone().offset(Offset { x: 30, y: 1 }), buf);
|
||||
//Line::from(match bbt {
|
||||
//Some(bbt) => format!("{:.01}", bbt.bpm),
|
||||
//None => String::from("(none)")
|
||||
//}).render(area.clone().offset(Offset { x: 30, y: 2 }), buf);
|
||||
//Line::from("TimeSig:").render(area.clone().offset(Offset { x: 40, y: 1 }), buf);
|
||||
//Line::from(match bbt {
|
||||
//Some(bbt) => format!("{}/{}", bbt.sig_num, bbt.sig_denom),
|
||||
//None => String::from("(none)")
|
||||
//}).render(area.clone().offset(Offset { x: 40, y: 2 }), buf);
|
||||
//Line::from("Beat:").render(area.clone().offset(Offset { x: 50, y: 1 }), buf);
|
||||
//Line::from(match bbt {
|
||||
//Some(bbt) => format!("{}.{}.{}", bbt.bar, bbt.beat, bbt.tick),
|
||||
//None => String::from("(none)")
|
||||
//}).render(area.clone().offset(Offset { x: 50, y: 2 }), buf);
|
||||
//}
|
||||
}
|
||||
|
||||
//pub fn render (
|
||||
//state: &mut Transport,
|
||||
//stdout: &mut Stdout,
|
||||
//mut offset: (u16, u16)
|
||||
//) -> Result<(), Box<dyn Error>> {
|
||||
//let move_to = |col, row| MoveTo(offset.0 + col, offset.1 + row);
|
||||
//stdout.queue(move_to( 1, 0))?.queue(
|
||||
//Print("Project: ")
|
||||
//)?.queue(move_to(10, 0))?.queue(
|
||||
//PrintStyledContent(state.title.clone().white().bold())
|
||||
//)?;
|
||||
|
||||
//if let Ok(position) = state.transport.query() {
|
||||
//let frame = position.pos.frame();
|
||||
//let rate = position.pos.frame_rate();
|
||||
//let bbt = position.pos.bbt().map(|mut bbt|*bbt
|
||||
//.with_bpm(state.bpm)
|
||||
//.with_timesig(state.timesig.0, state.timesig.1));
|
||||
//stdout
|
||||
//.queue(move_to( 1, 1))?.queue(Print("Frame: "))?
|
||||
//.queue(move_to( 1, 2))?.queue(
|
||||
//PrintStyledContent(
|
||||
//format!("{frame}").white().bold(),
|
||||
//))?
|
||||
//.queue(move_to(11, 1))?.queue(Print("Rate: "))?
|
||||
//.queue(move_to(11, 2))?.queue(
|
||||
//PrintStyledContent(match rate {
|
||||
//Some(rate) => format!("{rate}Hz"),
|
||||
//None => String::from("(none)"),
|
||||
//}.white().bold())
|
||||
//)?
|
||||
//.queue(move_to(20, 1))?.queue(Print("Time: "))?
|
||||
//.queue(move_to(20, 2))?.queue(
|
||||
//PrintStyledContent(match rate {
|
||||
//Some(rate) => format!("{:.03}", frame as f64 / rate as f64),
|
||||
//None => String::from("(none)")
|
||||
//}.white().bold())
|
||||
//)?
|
||||
//.queue(move_to(30, 1))?.queue(Print("BPM: "))?
|
||||
//.queue(move_to(30, 2))?.queue(
|
||||
//PrintStyledContent(match bbt {
|
||||
//Some(bbt) => format!("{:.01}", bbt.bpm),
|
||||
//None => String::from("(none)")
|
||||
//}.white().bold())
|
||||
//)?
|
||||
//.queue(move_to(39, 1))?.queue(Print("Timesig: "))?
|
||||
//.queue(move_to(39, 2))?.queue(
|
||||
//PrintStyledContent(match bbt {
|
||||
//Some(bbt) => format!("{}/{}", bbt.sig_num, bbt.sig_denom),
|
||||
//None => String::from("(none)")
|
||||
//}.white().bold())
|
||||
//)?
|
||||
//.queue(move_to(50, 1))?.queue(Print("Beat: "))?
|
||||
//.queue(move_to(50, 2))?.queue(
|
||||
//PrintStyledContent(match bbt {
|
||||
//Some(bbt) => format!("{}.{}.{}", bbt.bar, bbt.beat, bbt.tick),
|
||||
//None => String::from("(none)")
|
||||
//}.white().bold())
|
||||
//)?;
|
||||
//}
|
||||
//Ok(())
|
||||
//}
|
||||
|
||||
pub fn handle (_: &mut Transport, _: &AppEvent) -> Usually<bool> {
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
pub const ACTIONS: [(&'static str, &'static str);4] = [
|
||||
("?", "Toggle help"),
|
||||
("(Shift-)Tab", "Switch pane"),
|
||||
("Arrows", "Navigate"),
|
||||
("(Shift-)Space", "⯈ Play/pause"),
|
||||
];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue