tabula rasa

This commit is contained in:
🪞👃🪞 2024-05-23 21:18:56 +03:00
commit 11a9f3ba50
33 changed files with 1937 additions and 0 deletions

177
src/mixer.rs Normal file
View file

@ -0,0 +1,177 @@
use std::error::Error;
use std::io::{stdout, Write};
use std::thread::spawn;
use std::time::Duration;
use std::sync::{
Arc,
atomic::{AtomicBool, Ordering},
mpsc::{channel, Sender, Receiver}
};
pub struct Mixer {
exit: bool,
cols: u16,
rows: u16,
tracks: Vec<Track>,
selected_track: usize,
selected_column: usize,
}
pub struct Track {
name: String,
gain: f64,
level: f64,
pan: f64,
route: String,
}
impl Mixer {
pub fn new () -> Self {
Self {
exit: false,
cols: 0,
rows: 0,
selected_column: 0,
selected_track: 1,
tracks: vec! [
Track {
name: "Track 1".into(), gain: 0.0, level: 0.0, pan: 0.0, route: "Bus 1".into()
},
Track {
name: "Track 2".into(), gain: 0.0, level: 0.0, pan: 0.0, route: "Bus 2".into()
},
Track {
name: "Track 3".into(), gain: 0.0, level: 0.0, pan: 0.0, route: "Bus 1".into()
},
Track {
name: "Track 4".into(), gain: 0.0, level: 0.0, pan: 0.0, route: "Bus 2".into()
},
Track {
name: "Bus 1".into(), gain: 0.0, level: 0.0, pan: 0.0, route: "Mix".into()
},
Track {
name: "Bus 2".into(), gain: 0.0, level: 0.0, pan: 0.0, route: "Mix".into()
},
Track {
name: "Mix".into(), gain: 0.0, level: 0.0, pan: 0.0, route: "Output".into()
},
]
}
}
pub fn run_tui () -> Result<(), Box<dyn Error>> {
let mut app = Self::new();
let sleep = std::time::Duration::from_millis(16);
let mut stdout = std::io::stdout();
crossterm::terminal::enable_raw_mode()?;
let (tx, input) = channel::<crossterm::event::Event>();
let exited = Arc::new(AtomicBool::new(false));
// Spawn the input thread
let exit_input_thread = exited.clone();
spawn(move || {
loop {
// Exit if flag is set
if exit_input_thread.fetch_and(true, Ordering::Relaxed) {
break
}
// Listen for events and send them to the main thread
if crossterm::event::poll(Duration::from_millis(100)).is_ok() {
if tx.send(crossterm::event::read().unwrap()).is_err() {
break
}
}
}
});
loop {
app.render(&mut stdout)?;
app.handle(input.recv()?)?;
if app.exit {
crossterm::terminal::disable_raw_mode()?;
break
}
}
Ok(())
}
fn handle (&mut self, event: crossterm::event::Event) -> Result<(), Box<dyn Error>> {
use crossterm::event::{Event, KeyCode, KeyModifiers};
if let Event::Key(event) = event {
match event.code {
KeyCode::Char('c') => {
if event.modifiers == KeyModifiers::CONTROL {
self.exit = true;
}
},
KeyCode::Down => {
self.selected_track = (self.selected_track + 1) % self.tracks.len();
println!("{}", self.selected_track);
}
KeyCode::Up => {
if self.selected_track == 0 {
self.selected_track = self.tracks.len() - 1;
} else {
self.selected_track = self.selected_track - 1;
}
println!("{}", self.selected_track);
}
_ => {
println!("{event:?}");
}
}
}
Ok(())
}
fn render (&mut self, stdout: &mut std::io::Stdout) -> Result<(), Box<dyn Error>> {
use crossterm::{*, style::{*, Stylize}};
let (cols, rows) = terminal::size()?;
if true || cols != self.cols || rows != self.rows { // TODO perf
self.cols = cols;
self.rows = rows;
stdout
.queue(terminal::Clear(terminal::ClearType::All))?
.queue(cursor::Hide)?
.queue(cursor::MoveTo(1, 0))?
.queue(PrintStyledContent("[Arrows]".yellow().bold()))?
.queue(cursor::MoveTo(1, 1))?
.queue(PrintStyledContent("Navigate".yellow()))?
.queue(cursor::MoveTo(11, 0))?
.queue(PrintStyledContent("[+/-]".yellow().bold()))?
.queue(cursor::MoveTo(11, 1))?
.queue(PrintStyledContent("Adjust value".yellow()))?
.queue(cursor::MoveTo(25, 0))?
.queue(PrintStyledContent("[Ins/Del]".yellow().bold()))?
.queue(cursor::MoveTo(25, 1))?
.queue(PrintStyledContent("Add/remove track".yellow()))?
.queue(cursor::MoveTo(0, 3))?.queue(Print(
" Name Gain Pre Level Pan Post Route"))?;
for (i, track) in self.tracks.iter().enumerate() {
let row = 4 + i as u16;
let mut content = format!(
" {:7} █ {:.1}dB █ [ ] █ {:.1}dB C █ [ ] {:7} ",
track.name,
track.gain,
track.level,
track.route,
).bold();
if i == self.selected_track {
content = content.reverse();
}
stdout
.queue(cursor::MoveTo(0, row))?
.queue(PrintStyledContent(content))?;
}
stdout
.flush()?;
}
Ok(())
}
}