1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use cursive_core::{
Printer, Vec2, View,
theme::{Color, ColorStyle}
};
use rand::{
Rng, thread_rng,
prelude::SliceRandom as _
};
use audiovis::RawVisualizer;
use mlounge_core::library::Song;
pub struct WaveVisualizer {
wave: RawVisualizer,
latest_data: Vec<f32>,
art_path: String,
colors: Vec<Color>,
width: usize
}
impl WaveVisualizer {
pub fn new() -> WaveVisualizer {
WaveVisualizer {
wave: RawVisualizer::new(),
latest_data: vec![],
art_path: String::new(),
colors: vec![],
width: 0
}
}
pub fn update(&mut self, song: &Song) {
if self.width == 0 { return; }
let mut rand = thread_rng();
self.latest_data = self.wave.get_wave_data(self.width / 2);
if self.latest_data.len() < 4 { return; }
if let Some(path) = song.get_art_path() {
if self.art_path != path || self.latest_data[3] >= 0.25 {
self.colors.clear();
self.art_path = path;
let colors = song.cursive_album_colors();
let num_colors = rand.gen_range(5..20);
self.colors = colors.choose_multiple(&mut rand, num_colors).copied().collect();
}
}
}
}
impl View for WaveVisualizer {
fn draw(&self, printer: &Printer) {
if self.colors.is_empty() { return; }
let width = printer.size.x;
let height = printer.size.y;
let mut latest_data = self.latest_data.clone();
latest_data.resize(width / 2, 0.);
let mut wave = latest_data.clone();
wave.reverse();
wave.extend_from_slice(&latest_data);
let mut color_i = 0;
let color_m = width / self.colors.len();
for (i, level) in wave.iter().enumerate() {
let style = ColorStyle::new(self.colors[color_i], Color::TerminalDefault);
let int_level = (level * height as f32) as usize / 3;
printer.with_color(style, |printer| {
printer.print_vline((i, height - int_level), int_level, "█");
printer.print((i, height - 1), "█");
});
if i % color_m == 0 && i > 0 && i < width { color_i += 1; }
if color_i >= self.colors.len() { color_i = 0; }
}
}
fn required_size(&mut self, constraint: Vec2) -> Vec2 {
self.width = constraint.x;
constraint
}
}
impl Default for WaveVisualizer {
fn default() -> Self { Self::new() }
}