-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit, basic waveform rendering with tui
- Loading branch information
0 parents
commit c638bc8
Showing
7 changed files
with
497 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/target | ||
*.wav | ||
*.aif* | ||
venv | ||
.vscode | ||
Cargo.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
[package] | ||
name = "audeye" | ||
version = "0.1.0" | ||
edition = "2018" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
structopt = { version = "0.3", default-features = false } | ||
hound = { version = "3.4"} | ||
textplots = { version = "0.8" } | ||
terminal_size = { version = "0.1.17"} | ||
sndfile = { version = "0.0.4", features = ["ndarray_features"]} | ||
rayon = "1.5.1" | ||
tui = "0.16" | ||
termion = "1.5" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
use std::io; | ||
use std::sync::mpsc; | ||
use std::thread; | ||
use std::time::Duration; | ||
|
||
use termion::event::Key; | ||
use termion::input::TermRead; | ||
|
||
pub enum Event<I> { | ||
Input(I), | ||
Tick, | ||
} | ||
|
||
/// A small event handler that wrap termion input and tick events. Each event | ||
/// type is handled in its own thread and returned to a common `Receiver` | ||
pub struct Events { | ||
rx: mpsc::Receiver<Event<Key>>, | ||
input_handle: thread::JoinHandle<()>, | ||
tick_handle: thread::JoinHandle<()>, | ||
} | ||
|
||
#[derive(Debug, Clone, Copy)] | ||
pub struct Config { | ||
pub tick_rate: Duration, | ||
} | ||
|
||
impl Default for Config { | ||
fn default() -> Config { | ||
Config { | ||
tick_rate: Duration::from_millis(250), | ||
} | ||
} | ||
} | ||
|
||
impl Events { | ||
pub fn new() -> Events { | ||
Events::with_config(Config::default()) | ||
} | ||
|
||
pub fn with_config(config: Config) -> Events { | ||
let (tx, rx) = mpsc::channel(); | ||
let input_handle = { | ||
let tx = tx.clone(); | ||
thread::spawn(move || { | ||
let stdin = io::stdin(); | ||
for evt in stdin.keys() { | ||
if let Ok(key) = evt { | ||
if let Err(err) = tx.send(Event::Input(key)) { | ||
eprintln!("{}", err); | ||
return; | ||
} | ||
} | ||
} | ||
}) | ||
}; | ||
let tick_handle = { | ||
thread::spawn(move || loop { | ||
if let Err(err) = tx.send(Event::Tick) { | ||
eprintln!("{}", err); | ||
break; | ||
} | ||
thread::sleep(config.tick_rate); | ||
}) | ||
}; | ||
Events { | ||
rx, | ||
input_handle, | ||
tick_handle, | ||
} | ||
} | ||
|
||
pub fn next(&self) -> Result<Event<Key>, mpsc::RecvError> { | ||
self.rx.recv() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
|
||
// use std::fs::File; | ||
use structopt::StructOpt; | ||
use hound; | ||
use terminal_size::terminal_size; | ||
use tui::layout; | ||
use tui::style::Modifier; | ||
use tui::widgets::Dataset; | ||
use tui::widgets::GraphType; | ||
use std::convert::From; | ||
use std::convert::TryFrom; | ||
use std::convert::TryInto; | ||
use std::thread::panicking; | ||
use std::cmp::max; | ||
extern crate sndfile; | ||
use crate::render::waveform; | ||
use crate::sndfile::SndFileIO; | ||
use std::io::SeekFrom; | ||
|
||
|
||
|
||
mod event; | ||
use crate::event::{Event, Events}; | ||
|
||
mod render; | ||
use crate::render::renderer::Renderer; | ||
use crate::render::waveform::WaveformRenderer; | ||
// use crate::util:: | ||
|
||
|
||
// use crate::util::event::{Config, Event, Events}; | ||
use std::{error::Error, io, time::Duration}; | ||
use termion::{event::Key, input::MouseTerminal, raw::IntoRawMode, screen::AlternateScreen}; | ||
use tui::{ | ||
backend::TermionBackend, | ||
layout::{Constraint, Direction, Layout, Rect}, | ||
style::Color, | ||
style::Style, | ||
widgets::{ | ||
canvas::{Canvas, Map, MapResolution, Rectangle}, | ||
Block, Borders, Chart, Axis | ||
}, | ||
text::Span, | ||
Terminal, | ||
symbols | ||
}; | ||
|
||
|
||
|
||
#[derive(StructOpt)] | ||
struct CliArgs { | ||
// The file to read | ||
#[structopt(parse(from_os_str), help = "The path of the file to analyze")] | ||
path: std::path::PathBuf, | ||
|
||
// Normalize option | ||
// unused for now | ||
#[structopt(short = "n", long = "normalize")] | ||
normalize: bool, | ||
} | ||
|
||
|
||
fn main() -> Result<(), io::Error> { | ||
// Get some infos about the terminal | ||
// let (width, height) = terminal_size().expect("Unable to get terminal size"); | ||
|
||
// Get cli args | ||
let args = CliArgs::from_args(); | ||
|
||
// Setup UI | ||
let stdout = io::stdout().into_raw_mode()?; | ||
let stdout = MouseTerminal::from(stdout); | ||
let stdout = AlternateScreen::from(stdout); | ||
let backend = TermionBackend::new(stdout); | ||
let mut terminal = Terminal::new(backend)?; | ||
|
||
let events = Events::new(); | ||
|
||
|
||
// Compute the size of each block to fit the screen | ||
let block_count: u16 = 1920 / 4 ; | ||
|
||
|
||
let mut waveform_render = WaveformRenderer::new(block_count, &args.path); | ||
let channels = waveform_render.channels; | ||
let chunk_count: u32 = max(2, channels).try_into().expect(""); | ||
let layout_constraints = vec![Constraint::Ratio(1, chunk_count); chunk_count as usize]; | ||
|
||
|
||
loop { | ||
terminal.draw(|f| { | ||
let chunks = Layout::default() | ||
.direction(Direction::Vertical) | ||
.constraints(layout_constraints.as_ref()) | ||
.split(f.size()); | ||
|
||
for ch_idx in 0..channels { | ||
match waveform_render.get_representation(ch_idx) { | ||
Some(chart) => f.render_widget(chart, chunks[ch_idx]), | ||
None => () | ||
} | ||
} | ||
|
||
})?; | ||
|
||
let event = events.next().expect(""); | ||
|
||
match event { | ||
Event::Input(input) => { | ||
if input == Key::Char('q') { | ||
break; | ||
} | ||
} | ||
Event::Tick => { | ||
continue; | ||
} | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
|
||
// // let shape = Shape::Bars(); | ||
// let graph_height: u32 = u32::max(height.0.into(), 32); | ||
// Chart::new_with_y_range((width.0).into(), graph_height, 0., block_count as f32, -1., 1.) | ||
// .lineplot(&Shape::Lines(p_data.as_slice())) | ||
// .lineplot(&Shape::Lines(n_data.as_slice())) | ||
// .display(); | ||
// Chart::new(block_count.into(), graph_height, 0., block_count as f32) | ||
// .lineplot(&Shape::Lines(p_data.as_slice())) | ||
// .lineplot(&Shape::Lines(n_data.as_slice())) | ||
// .display(); | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub mod renderer; | ||
pub mod waveform; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
use tui::widgets::Widget; | ||
|
||
|
||
pub trait Renderer<'a, T : Widget> { | ||
fn get_representation(&'a mut self, channel: usize) -> Option<T>; | ||
} | ||
|
Oops, something went wrong.