Skip to content

Commit 22b5b35

Browse files
committed
feat(audio): upgrade rodio to 0.21, no waveform visualization
1 parent 1fc0adb commit 22b5b35

3 files changed

Lines changed: 19 additions & 167 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 96 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,4 @@ edition = "2024"
66
[dependencies]
77
rodio = "0.21"
88
crossterm = "0.29"
9-
ratatui = "0.29"
10-
rand = "0.9"
9+
ratatui = "0.29"

src/main.rs

Lines changed: 17 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,13 @@ use crossterm::{
1010
execute,
1111
terminal::{EnterAlternateScreen, LeaveAlternateScreen, SetTitle, disable_raw_mode, enable_raw_mode},
1212
};
13-
use rand::prelude::*;
1413
use ratatui::{
1514
Frame, Terminal,
1615
backend::CrosstermBackend,
1716
layout::{Alignment, Constraint, Direction, Layout},
1817
style::{Color, Modifier, Style},
1918
text::{Line, Span},
20-
widgets::{BarChart, Block, Borders, Gauge, List, ListItem, ListState, Paragraph},
19+
widgets::{Block, Borders, Gauge, List, ListItem, ListState, Paragraph},
2120
};
2221
use rodio::{Decoder, OutputStreamBuilder, Sink, Source};
2322

@@ -45,35 +44,9 @@ struct Player {
4544
song_duration: Option<Duration>,
4645
seek_offset: Duration,
4746
show_controls_popup: bool,
48-
waveform_data: Vec<u64>,
4947
}
5048

5149
impl Player {
52-
fn generate_waveform(&mut self) {
53-
if !self.is_playing {
54-
self.waveform_data = vec![0; 20];
55-
return;
56-
}
57-
58-
// Generate simplified animated waveform for performance
59-
let elapsed = self.get_playback_progress().0;
60-
let time_factor = elapsed.as_secs_f32();
61-
62-
let mut rng = rand::rng();
63-
let base_level = 40;
64-
65-
self.waveform_data = (0..20)
66-
.map(|i| {
67-
// Create wave pattern based on time and position
68-
let phase = (i as f32 * 0.3 + time_factor * 2.0).sin();
69-
let secondary_wave = (i as f32 * 0.7 + time_factor * 1.5).cos();
70-
let noise = rng.random::<f32>() * 15.0;
71-
72-
let amplitude = base_level as f32 + phase * 25.0 + secondary_wave * 15.0 + noise;
73-
amplitude.max(5.0).min(100.0) as u64
74-
})
75-
.collect();
76-
}
7750

7851
fn update_terminal_title(&self) {
7952
if self.songs.is_empty() {
@@ -131,7 +104,6 @@ impl Player {
131104
song_duration: None,
132105
seek_offset: Duration::from_secs(0),
133106
show_controls_popup: false,
134-
waveform_data: vec![0; 20],
135107
};
136108

137109
// Set initial terminal title
@@ -230,13 +202,17 @@ impl Player {
230202
}
231203

232204
let next_index = if self.random_mode {
233-
let mut rng = rand::rng();
205+
// Simple random selection using timestamp
206+
let timestamp = std::time::SystemTime::now()
207+
.duration_since(std::time::UNIX_EPOCH)
208+
.unwrap_or_default()
209+
.as_nanos() as usize;
234210
let mut indices: Vec<usize> = (0..self.songs.len()).collect();
235-
indices.remove(self.current_index);
211+
indices.retain(|&i| i != self.current_index);
236212
if indices.is_empty() {
237213
self.current_index
238214
} else {
239-
*indices.choose(&mut rng).unwrap()
215+
indices[timestamp % indices.len()]
240216
}
241217
} else if self.current_index + 1 >= self.songs.len() {
242218
if self.loop_mode { 0 } else { self.current_index }
@@ -253,13 +229,17 @@ impl Player {
253229
}
254230

255231
let prev_index = if self.random_mode {
256-
let mut rng = rand::rng();
232+
// Simple random selection using timestamp
233+
let timestamp = std::time::SystemTime::now()
234+
.duration_since(std::time::UNIX_EPOCH)
235+
.unwrap_or_default()
236+
.as_nanos() as usize;
257237
let mut indices: Vec<usize> = (0..self.songs.len()).collect();
258-
indices.remove(self.current_index);
238+
indices.retain(|&i| i != self.current_index);
259239
if indices.is_empty() {
260240
self.current_index
261241
} else {
262-
*indices.choose_mut(&mut rng).unwrap()
242+
indices[timestamp % indices.len()]
263243
}
264244
} else if self.current_index == 0 {
265245
if self.loop_mode { self.songs.len() - 1 } else { 0 }
@@ -429,7 +409,6 @@ fn ui(f: &mut Frame, player: &Player) {
429409
.constraints([
430410
Constraint::Length(3), // Title
431411
Constraint::Min(8), // Song list
432-
Constraint::Length(8), // Waveform
433412
Constraint::Length(3), // Progress bar
434413
Constraint::Length(3), // Status
435414
])
@@ -476,34 +455,6 @@ fn ui(f: &mut Frame, player: &Player) {
476455

477456
f.render_stateful_widget(songs_list, chunks[1], &mut player.list_state.clone());
478457

479-
// Waveform visualization
480-
let waveform_data: Vec<(&str, u64)> = player.waveform_data
481-
.iter()
482-
.enumerate()
483-
.map(|(i, &value)| {
484-
let label = if i % 4 == 0 {
485-
format!("{}", i + 1)
486-
} else {
487-
" ".to_string()
488-
};
489-
(Box::leak(label.into_boxed_str()) as &str, value)
490-
})
491-
.collect();
492-
493-
let waveform_chart = BarChart::default()
494-
.block(
495-
Block::default()
496-
.borders(Borders::ALL)
497-
.title("Waveform")
498-
.border_style(Style::default().fg(PRIMARY_COLOR)),
499-
)
500-
.data(&waveform_data)
501-
.bar_width(3)
502-
.bar_gap(1)
503-
.bar_style(Style::default().fg(HIGHLIGHT_COLOR))
504-
.value_style(Style::default().fg(Color::White).add_modifier(Modifier::BOLD));
505-
f.render_widget(waveform_chart, chunks[2]);
506-
507458
// Progress bar
508459
let (elapsed, total) = player.get_playback_progress();
509460
let progress_ratio = if let Some(duration) = total {
@@ -534,7 +485,7 @@ fn ui(f: &mut Frame, player: &Player) {
534485
.gauge_style(Style::default().fg(PRIMARY_COLOR))
535486
.ratio(progress_ratio)
536487
.label(progress_label);
537-
f.render_widget(progress_bar, chunks[3]);
488+
f.render_widget(progress_bar, chunks[2]);
538489

539490
// Status
540491
let mode_text = if player.random_mode { "RANDOM" } else { "NORMAL" };
@@ -551,7 +502,7 @@ fn ui(f: &mut Frame, player: &Player) {
551502
.title("Status")
552503
.border_style(Style::default().fg(PRIMARY_COLOR)),
553504
);
554-
f.render_widget(status, chunks[4]);
505+
f.render_widget(status, chunks[3]);
555506

556507
// Controls popup
557508
if player.show_controls_popup {
@@ -689,9 +640,6 @@ fn run_player() -> Result<(), Box<dyn std::error::Error>> {
689640

690641
fn main_loop(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>, player: &mut Player) -> Result<(), Box<dyn std::error::Error>> {
691642
loop {
692-
// Update waveform data for real-time visualization
693-
player.generate_waveform();
694-
695643
terminal.draw(|f| ui(f, player))?;
696644

697645
if let Ok(true) = event::poll(Duration::from_millis(100)) {

0 commit comments

Comments
 (0)