fix: BigBuffer prevents sequencer from crashing

This commit is contained in:
🪞👃🪞 2024-08-02 23:19:44 +03:00
parent 96570d0267
commit 96e17e7f7c
4 changed files with 59 additions and 30 deletions

View file

@ -15,7 +15,7 @@ use ::winit::{
window::{Window, WindowId},
platform::x11::EventLoopBuilderExtX11
};
use ::suil::{self};
use ::suil_rs::{self};
impl Plugin {
pub fn lv2 (name: &str, path: &str) -> Usually<JackDevice> {

View file

@ -20,7 +20,7 @@ impl Iterator for Voice {
if self.position < sample.end {
let position = self.position;
self.position = self.position + 1;
return sample.channels[0].get(position).map(|amplitude|[
return sample.channels[0].get(position).map(|_amplitude|[
sample.channels[0][position] * self.velocity,
sample.channels[0][position] * self.velocity,
])

View file

@ -132,7 +132,7 @@ pub struct Sequencer {
pub entered: bool,
pub phrase: Option<Arc<RwLock<Phrase>>>,
pub buffer: Buffer,
pub buffer: BigBuffer,
pub keys: Buffer,
/// Highlight input keys
pub keys_in: [bool; 128],
@ -158,7 +158,7 @@ render!(Sequencer |self, buf, area| {
impl Sequencer {
pub fn new () -> Self {
Self {
buffer: Buffer::empty(Rect::default()),
buffer: Default::default(),
keys: keys_vert(),
entered: false,
focused: false,
@ -184,14 +184,14 @@ impl Sequencer {
pub fn show (&mut self, phrase: Option<&Arc<RwLock<Phrase>>>) -> Usually<()> {
self.phrase = phrase.map(Clone::clone);
if let Some(ref phrase) = self.phrase {
let width = u16::MAX.min(phrase.read().unwrap().length as u16);
let mut buffer = Buffer::empty(Rect { x: 0, y: 0, width, height: 64 });
let width = usize::MAX.min(phrase.read().unwrap().length);
let mut buffer = BigBuffer::new(width, 64);
let phrase = phrase.read().unwrap();
fill_seq_bg(&mut buffer, phrase.length, self.ppq)?;
fill_seq_fg(&mut buffer, &phrase)?;
self.buffer = buffer;
} else {
self.buffer = Buffer::empty(Rect::default())
self.buffer = Default::default();
}
Ok(())
}
@ -248,13 +248,15 @@ impl Sequencer {
width: area.width - Self::H_KEYS_OFFSET,
height: area.height - 2
};
buffer_update(buf, area, &|cell, x, y|{
let src_x = (x + self.time_axis.start) * self.time_axis.scale;
let src_y = y + self.note_axis.start;
if src_x < self.buffer.area.width && src_y < self.buffer.area.height - 1 {
let src = self.buffer.get(src_x, self.buffer.area.height - src_y);
cell.set_symbol(src.symbol());
cell.set_fg(src.fg);
buffer_update(buf, area, &move |cell, x, y|{
let src_x = ((x + self.time_axis.start) * self.time_axis.scale) as usize;
let src_y = (y + self.note_axis.start) as usize;
if src_x < self.buffer.width && src_y < self.buffer.height - 1 {
let src = self.buffer.get(src_x, self.buffer.height - src_y);
src.map(|src|{
cell.set_symbol(src.symbol());
cell.set_fg(src.fg);
});
}
});
Ok(area)
@ -371,20 +373,22 @@ fn key_colors (index: u16) -> (Color, Color) {
}
}
fn fill_seq_bg (buf: &mut Buffer, length: usize, ppq: usize) -> Usually<()> {
for x in 0 .. buf.area.width - buf.area.x {
fn fill_seq_bg (buf: &mut BigBuffer, length: usize, ppq: usize) -> Usually<()> {
for x in 0..buf.width {
if x as usize >= length {
break
}
let style = Style::default();
let cell = buf.get_mut(x, buf.area.y);
cell.set_char('-');
cell.set_style(style);
for y in 0 .. buf.area.height - buf.area.y {
let cell = buf.get_mut(x, y);
cell.set_char(char_seq_bg(ppq, x));
cell.set_fg(Color::Gray);
cell.modifier = Modifier::DIM;
buf.get_mut(x, 0).map(|cell|{
cell.set_char('-');
cell.set_style(style);
});
for y in 0 .. buf.height {
buf.get_mut(x, y).map(|cell|{
cell.set_char(char_seq_bg(ppq, x as u16));
cell.set_fg(Color::Gray);
cell.modifier = Modifier::DIM;
});
}
}
Ok(())
@ -402,9 +406,9 @@ fn char_seq_bg (ppq: usize, x: u16) -> char {
}
}
fn fill_seq_fg (buf: &mut Buffer, phrase: &Phrase) -> Usually<()> {
fn fill_seq_fg (buf: &mut BigBuffer, phrase: &Phrase) -> Usually<()> {
let mut notes_on = [false;128];
for x in 0 .. buf.area.width - buf.area.x {
for x in 0..buf.width {
if x as usize >= phrase.length {
break
}
@ -426,7 +430,7 @@ fn fill_seq_fg (buf: &mut Buffer, phrase: &Phrase) -> Usually<()> {
}
}
}
for y in 0 .. (buf.area.height - buf.area.y) / 2 {
for y in 0..buf.height/2 {
if y >= 64 {
break
}
@ -434,9 +438,10 @@ fn fill_seq_fg (buf: &mut Buffer, phrase: &Phrase) -> Usually<()> {
notes_on[y as usize * 2],
notes_on[y as usize * 2 + 1],
) {
let cell = buf.get_mut(x, y);
cell.set_char(block);
cell.set_fg(Color::White);
buf.get_mut(x, y).map(|cell|{
cell.set_char(block);
cell.set_fg(Color::White);
});
}
}
if phrase.percussive {

View file

@ -18,3 +18,27 @@ render!(App |self, buf, area| {
}
Ok(area)
});
#[derive(Default)]
pub struct BigBuffer {
pub width: usize,
pub height: usize,
pub content: Vec<Cell>
}
impl BigBuffer {
pub fn new (width: usize, height: usize) -> Self {
Self { width, height, content: vec![Cell::default(); width*height] }
}
pub fn get (&self, x: usize, y: usize) -> Option<&Cell> {
let i = self.index_of(x, y);
self.content.get(i)
}
pub fn get_mut (&mut self, x: usize, y: usize) -> Option<&mut Cell> {
let i = self.index_of(x, y);
self.content.get_mut(i)
}
pub fn index_of (&self, x: usize, y: usize) -> usize {
y * self.width + x
}
}