fix sequencer x offset and do fewer clones

This commit is contained in:
🪞👃🪞 2024-07-09 14:13:55 +03:00
parent 876d26e287
commit b673e4c68d
2 changed files with 57 additions and 46 deletions

View file

@ -2,10 +2,10 @@
(scene { :name "Intro" } _ 0 _ _)
(scene { :name "Hook" } 0 1 0 _)
(scene { :name "Verse" } 2 2 1 _)
(scene { :name "Chorus" } 1 3 2 _)
(scene { :name "Verse" } 1 2 1 _)
(scene { :name "Chorus" } 2 3 2 _)
(scene { :name "Bridge" } 3 4 3 _)
(scene { :name "Outro" } _ 1 4 _)
(scene { :name "Outro" } 4 1 4 _)
(track { :name "Drums" :gain +0.0 }
(phrase { :name "4 kicks" :beats 4 :steps 16 }
@ -46,6 +46,24 @@
(:11 (35 100) (36 100))
(:12 (44 100) (40 100))
(:14 (44 100)))
(phrase { :name "Trapping" :beats 4 :steps 48 }
(:00 (42 100) (36 100) (34 100))
(:01 (42 100))
(:02 (42 100))
(:06 (42 100) (36 100))
(:06 (42 100) (36 100) (34 100))
(:07 (42 100))
(:08 (42 100))
(:12 (42 100))
(:18 (42 100))
(:24 (42 100) (38 100) (40 50))
(:27 (42 100) (36 50))
(:30 (42 100) (34 100))
(:33 (42 100) (36 50))
(:36 (42 90))
(:39 (42 80))
(:42 (42 70) (38 100) (40 50))
(:45 (42 60)))
(sampler { :name "DrumKit1" :dir "/home/user/Lab/Music/pak" }
(sample { :midi 34 :name "808" :file "808.wav" })
(sample { :midi 35 :name "KC1" :file "kik.wav" })

View file

@ -68,16 +68,21 @@ impl<'a> SequencerView<'a> {
Style::default().green().dim()
})
}
fn style_timer_step (now: usize, step: usize, next_step: usize) -> Style {
if step <= now && now < next_step {
Style::default().yellow().bold().not_dim()
} else {
Style::default()
}
}
}
impl<'a> SequencerView<'a> {
fn horizontal_draw (&self, buf: &mut Buffer, area: Rect) -> Usually<()> {
self.horizontal_keys(buf, area)?;
self.horizontal_quant(buf, area);
if let Some(phrase) = self.phrase {
self.horizontal_timer(buf, area, phrase);
self.horizontal_lanes(buf, area, phrase);
}
self.horizontal_timer(buf, area, self.phrase);
self.horizontal_lanes(buf, area, self.phrase);
self.horizontal_cursor(buf, area);
Ok(())
}
@ -97,47 +102,39 @@ impl<'a> SequencerView<'a> {
c.blit(buf, x, y, self.style_focus());
}
fn horizontal_timer (&self, buf: &mut Buffer, area: Rect, phrase: &Phrase) {
let (time0, time_z, now) =
(self.time_start, self.time_zoom, self.now % phrase.length);
fn horizontal_timer (&self, buf: &mut Buffer, area: Rect, phrase: Option<&Phrase>) {
if phrase.is_none() {
return
}
let phrase = phrase.unwrap();
let (time0, time_z, now) = (self.time_start, self.time_zoom, self.now % phrase.length);
let Rect { x, width, .. } = area;
let offset = 5;
for x in x+offset..x+width-offset {
let step = (time0 + (x-offset) as usize) * time_z;
let next_step = (time0 + (x-offset) as usize + 1) * time_z;
let style = if step <= now && now < next_step {
Style::default().yellow().bold().not_dim()
} else {
Style::default()
};
let style = Self::style_timer_step(now, step, next_step);
"-".blit(buf, x, area.y, Some(style))
}
}
fn horizontal_keys (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
let (note0, notes_in, notes_out) = (self.note_start, self.notes_in, self.notes_out);
let dim = Style::default().not_dim();
let red = Style::default().red();
let yellow = Style::default().yellow();
let green = Style::default().green();
let mut cell_bg = Cell::default();
cell_bg.set_char('░');
cell_bg.set_style(dim.black());
cell_bg.set_style(Style::default().not_dim().black());
let mut cell_full = Cell::default();
cell_full.set_char('█');
cell_full.set_style(dim);
cell_full.set_style(Style::default().not_dim());
let mut cell_hi = Cell::default();
cell_hi.set_char('▀');
cell_hi.set_style(dim);
cell_hi.set_style(Style::default().not_dim());
let mut cell_lo = Cell::default();
cell_lo.set_char('▄');
cell_lo.set_style(dim);
let cell_keys = [&cell_lo, &cell_lo, &cell_full, &cell_hi, &cell_hi, &cell_hi];
cell_lo.set_style(Style::default().not_dim());
let Rect { x, y, width, height } = area;
let height = height.min(128);
@ -237,7 +234,11 @@ impl<'a> SequencerView<'a> {
Ok(area)
}
fn horizontal_lanes (&self, buf: &mut Buffer, area: Rect, phrase: &Phrase) {
fn horizontal_lanes (&self, buf: &mut Buffer, area: Rect, phrase: Option<&Phrase>) {
if phrase.is_none() {
return
}
let phrase = phrase.unwrap();
let (ppq, time_z, time0, note0) =
(self.ppq, self.time_zoom, self.time_start, self.note_start);
let bg = Style::default();
@ -245,19 +246,11 @@ impl<'a> SequencerView<'a> {
let Rect { x, y, width, height } = area;
let offset = 5;
let offset = 5;
let phrase_area = Rect {
x: x + offset, y, width: width - offset, height: height - 2
};
let mut cell_bg = Cell::default();
cell_bg.set_char('·');
cell_bg.set_style(bw);
let mut cell_bg_tick = Cell::default();
cell_bg_tick.set_char('|');
cell_bg_tick.set_style(bw);
let mut cell_a = Cell::default();
cell_a.set_char('▄');
cell_a.set_style(wh);
@ -272,26 +265,26 @@ impl<'a> SequencerView<'a> {
let mut steps = vec![];
for x in phrase_area.x .. phrase_area.x + phrase_area.width {
let step = (time0 + (x-offset) as usize) * time_z;
let next_step = (1 + time0 + (x-offset) as usize) * time_z;
let x0 = x.saturating_sub(phrase_area.x) as usize;
let step = (0 + time0 + x0) * time_z;
let next = (1 + time0 + x0) * time_z;
if step > phrase.length {
break
}
steps.push((x, step, next_step));
let cell = if step % ppq == 0 {
&cell_bg_tick
} else {
&cell_bg
};
steps.push((x, step, next));
for y in phrase_area.y .. phrase_area.y + phrase_area.height {
if y == phrase_area.y {
if step % (4 * ppq) == 0 {
format!("{}", 1 + step / (4 * ppq)).blit(buf, x, y, None);
} else if step % ppq == 0 {
*buf.get_mut(x, y) = cell.clone();
let cell = buf.get_mut(x, y);
cell.set_char(if step % ppq == 0 { '|' } else { '·' });
cell.set_style(bw);
}
} else {
*buf.get_mut(x, y) = cell.clone();
let cell = buf.get_mut(x, y);
cell.set_char(if step % ppq == 0 { '|' } else { '·' });
cell.set_style(bw);
}
}
}