mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
wip: p.57, e=81
This commit is contained in:
parent
0964ad3be4
commit
0c94c2af8f
11 changed files with 672 additions and 667 deletions
|
|
@ -767,3 +767,108 @@ pub(crate) fn keys_vert () -> Buffer {
|
|||
const NTH_OCTAVE: [&'static str; 11] = [
|
||||
"-2", "-1", "0", "1", "2", "3", "4", "5", "6", "7", "8",
|
||||
];
|
||||
|
||||
impl PhraseTui {
|
||||
pub fn put (&mut self) {
|
||||
if let (Some(phrase), Some(time), Some(note)) = (
|
||||
&self.phrase,
|
||||
self.time_axis.read().unwrap().point,
|
||||
self.note_axis.read().unwrap().point,
|
||||
) {
|
||||
let mut phrase = phrase.write().unwrap();
|
||||
let key: u7 = u7::from((127 - note) as u8);
|
||||
let vel: u7 = 100.into();
|
||||
let start = time;
|
||||
let end = (start + self.note_len) % phrase.length;
|
||||
phrase.notes[time].push(MidiMessage::NoteOn { key, vel });
|
||||
phrase.notes[end].push(MidiMessage::NoteOff { key, vel });
|
||||
self.buffer = Self::redraw(&phrase);
|
||||
}
|
||||
}
|
||||
/// Select which pattern to display. This pre-renders it to the buffer at full resolution.
|
||||
pub fn show (&mut self, phrase: Option<&Arc<RwLock<Phrase>>>) {
|
||||
if let Some(phrase) = phrase {
|
||||
self.phrase = Some(phrase.clone());
|
||||
self.time_axis.write().unwrap().clamp = Some(phrase.read().unwrap().length);
|
||||
self.buffer = Self::redraw(&*phrase.read().unwrap());
|
||||
} else {
|
||||
self.phrase = None;
|
||||
self.time_axis.write().unwrap().clamp = Some(0);
|
||||
self.buffer = Default::default();
|
||||
}
|
||||
}
|
||||
fn redraw (phrase: &Phrase) -> BigBuffer {
|
||||
let mut buf = BigBuffer::new(usize::MAX.min(phrase.length), 65);
|
||||
Self::fill_seq_bg(&mut buf, phrase.length, phrase.ppq);
|
||||
Self::fill_seq_fg(&mut buf, &phrase);
|
||||
buf
|
||||
}
|
||||
fn fill_seq_bg (buf: &mut BigBuffer, length: usize, ppq: usize) {
|
||||
for x in 0..buf.width {
|
||||
// Only fill as far as phrase length
|
||||
if x as usize >= length { break }
|
||||
// Fill each row with background characters
|
||||
for y in 0 .. buf.height {
|
||||
buf.get_mut(x, y).map(|cell|{
|
||||
cell.set_char(if ppq == 0 {
|
||||
'·'
|
||||
} else if x % (4 * ppq) == 0 {
|
||||
'│'
|
||||
} else if x % ppq == 0 {
|
||||
'╎'
|
||||
} else {
|
||||
'·'
|
||||
});
|
||||
cell.set_fg(Color::Rgb(48, 64, 56));
|
||||
cell.modifier = Modifier::DIM;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
fn fill_seq_fg (buf: &mut BigBuffer, phrase: &Phrase) {
|
||||
let mut notes_on = [false;128];
|
||||
for x in 0..buf.width {
|
||||
if x as usize >= phrase.length {
|
||||
break
|
||||
}
|
||||
if let Some(notes) = phrase.notes.get(x as usize) {
|
||||
if phrase.percussive {
|
||||
for note in notes {
|
||||
match note {
|
||||
MidiMessage::NoteOn { key, .. } =>
|
||||
notes_on[key.as_int() as usize] = true,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for note in notes {
|
||||
match note {
|
||||
MidiMessage::NoteOn { key, .. } =>
|
||||
notes_on[key.as_int() as usize] = true,
|
||||
MidiMessage::NoteOff { key, .. } =>
|
||||
notes_on[key.as_int() as usize] = false,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
for y in 0..buf.height {
|
||||
if y >= 64 {
|
||||
break
|
||||
}
|
||||
if let Some(block) = half_block(
|
||||
notes_on[y as usize * 2],
|
||||
notes_on[y as usize * 2 + 1],
|
||||
) {
|
||||
buf.get_mut(x, y).map(|cell|{
|
||||
cell.set_char(block);
|
||||
cell.set_fg(Color::White);
|
||||
});
|
||||
}
|
||||
}
|
||||
if phrase.percussive {
|
||||
notes_on.fill(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue