diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/audio.rs | 43 | ||||
| -rw-r--r-- | src/daemon.rs | 25 | ||||
| -rw-r--r-- | src/queue.rs | 23 |
3 files changed, 43 insertions, 48 deletions
diff --git a/src/audio.rs b/src/audio.rs index 386c041..62afd93 100644 --- a/src/audio.rs +++ b/src/audio.rs | |||
| @@ -199,30 +199,29 @@ fn audio_thread( | |||
| 199 | 199 | ||
| 200 | // Pre-decode some samples before starting playback to prevent buffer underrun | 200 | // Pre-decode some samples before starting playback to prevent buffer underrun |
| 201 | let channels = data.channels as usize; | 201 | let channels = data.channels as usize; |
| 202 | for _ in 0..50 { | 202 | for _ in 0..100 { |
| 203 | match data.format.next_packet() { | 203 | match data.format.next_packet() { |
| 204 | Ok(packet) => { | 204 | Ok(packet) => match data.decoder.decode(&packet) { |
| 205 | match data.decoder.decode(&packet) { | 205 | Ok(decoded) => { |
| 206 | Ok(decoded) => { | 206 | let spec = *decoded.spec(); |
| 207 | let spec = *decoded.spec(); | 207 | let mut sample_buf = symphonia::core::audio::SampleBuffer::< |
| 208 | let mut sample_buf = | 208 | f32, |
| 209 | symphonia::core::audio::SampleBuffer::<f32>::new( | 209 | >::new( |
| 210 | decoded.capacity() as u64, spec | 210 | decoded.capacity() as u64, spec |
| 211 | ); | 211 | ); |
| 212 | sample_buf.copy_interleaved_ref(decoded); | 212 | sample_buf.copy_interleaved_ref(decoded); |
| 213 | let samples = sample_buf.samples(); | 213 | let samples = sample_buf.samples(); |
| 214 | 214 | ||
| 215 | let resampled = if let Some(ratio) = data.resample_ratio { | 215 | let resampled = if let Some(ratio) = data.resample_ratio { |
| 216 | resample_linear(samples, ratio, channels) | 216 | resample_linear(samples, ratio, channels) |
| 217 | } else { | 217 | } else { |
| 218 | samples.to_vec() | 218 | samples.to_vec() |
| 219 | }; | 219 | }; |
| 220 | 220 | ||
| 221 | data.sample_buffer.extend(resampled); | 221 | data.sample_buffer.extend(resampled); |
| 222 | } | ||
| 223 | Err(_) => break, | ||
| 224 | } | 222 | } |
| 225 | } | 223 | Err(_) => break, |
| 224 | }, | ||
| 226 | Err(_) => break, | 225 | Err(_) => break, |
| 227 | } | 226 | } |
| 228 | } | 227 | } |
diff --git a/src/daemon.rs b/src/daemon.rs index 7488fc2..b79e67a 100644 --- a/src/daemon.rs +++ b/src/daemon.rs | |||
| @@ -454,7 +454,10 @@ fn process_command( | |||
| 454 | for file in &files { | 454 | for file in &files { |
| 455 | q.add_track(file.clone()); | 455 | q.add_track(file.clone()); |
| 456 | } | 456 | } |
| 457 | if was_empty && !was_playing && let Some(track) = q.current() { | 457 | if was_empty |
| 458 | && !was_playing | ||
| 459 | && let Some(track) = q.current() | ||
| 460 | { | ||
| 458 | audio.play(track.path.clone()); | 461 | audio.play(track.path.clone()); |
| 459 | notification::notify_track(track); | 462 | notification::notify_track(track); |
| 460 | } | 463 | } |
| @@ -519,24 +522,8 @@ fn process_command( | |||
| 519 | } | 522 | } |
| 520 | } | 523 | } |
| 521 | } | 524 | } |
| 522 | // Use pager if queue is longer than terminal height | 525 | // Always return full output - client can pipe to pager if needed |
| 523 | let terminal_rows = terminal_size::terminal_size() | 526 | output |
| 524 | .map(|(w, _)| w.0 as usize) | ||
| 525 | .unwrap_or(24); | ||
| 526 | if output.lines().count() > terminal_rows { | ||
| 527 | use std::process::{Command, Stdio}; | ||
| 528 | let pager = Command::new("less").arg("-R").stdin(Stdio::piped()).spawn(); | ||
| 529 | if let Ok(mut child) = pager { | ||
| 530 | use std::io::Write; | ||
| 531 | let _ = child.stdin.as_mut().unwrap().write_all(output.as_bytes()); | ||
| 532 | let _ = child.wait(); | ||
| 533 | "".to_string() | ||
| 534 | } else { | ||
| 535 | output | ||
| 536 | } | ||
| 537 | } else { | ||
| 538 | output | ||
| 539 | } | ||
| 540 | } | 527 | } |
| 541 | } else { | 528 | } else { |
| 542 | "Error accessing queue\n".to_string() | 529 | "Error accessing queue\n".to_string() |
diff --git a/src/queue.rs b/src/queue.rs index db329c6..f556ed3 100644 --- a/src/queue.rs +++ b/src/queue.rs | |||
| @@ -184,24 +184,29 @@ impl Queue { | |||
| 184 | 184 | ||
| 185 | fn restore_from_original(&mut self) { | 185 | fn restore_from_original(&mut self) { |
| 186 | if self.original_tracks.is_empty() { | 186 | if self.original_tracks.is_empty() { |
| 187 | eprintln!("DEBUG: original_tracks empty"); | ||
| 187 | self.shuffled_indices.clear(); | 188 | self.shuffled_indices.clear(); |
| 188 | return; | 189 | return; |
| 189 | } | 190 | } |
| 190 | 191 | ||
| 191 | let current_pos = self.position; | 192 | let current_pos = self.position; |
| 193 | let indices_len = self.shuffled_indices.len().min(10); | ||
| 194 | eprintln!("DEBUG restore: current_pos={}, tracks.len={}, shuffled_indices={:?}", | ||
| 195 | current_pos, self.tracks.len(), &self.shuffled_indices[..indices_len]); | ||
| 192 | 196 | ||
| 193 | // Find which tracks have been played (positions 0..=current_pos in shuffled order) | 197 | // Find which tracks have been played (positions 0..=current_pos in shuffled order) |
| 194 | // These are tracks whose shuffled_indices value is <= current_pos | ||
| 195 | let mut played_track_paths: Vec<std::path::PathBuf> = Vec::new(); | 198 | let mut played_track_paths: Vec<std::path::PathBuf> = Vec::new(); |
| 196 | for i in 0..=current_pos { | 199 | for i in 0..=current_pos { |
| 197 | if let Some(&idx) = self.shuffled_indices.get(i) { | 200 | if let Some(&idx) = self.shuffled_indices.get(i) |
| 198 | if let Some(track) = self.tracks.get(idx) { | 201 | && let Some(track) = self.tracks.get(idx) |
| 199 | played_track_paths.push(track.path.clone()); | 202 | { |
| 200 | } | 203 | eprintln!("DEBUG: played track at shuffled pos {} -> track idx {} = {:?}", |
| 204 | i, idx, track.path.file_name()); | ||
| 205 | played_track_paths.push(track.path.clone()); | ||
| 201 | } | 206 | } |
| 202 | } | 207 | } |
| 203 | 208 | ||
| 204 | // Keep the played tracks in their current order (shuffled order) | 209 | // Keep the played tracks in their current order |
| 205 | let mut new_tracks: Vec<Track> = Vec::new(); | 210 | let mut new_tracks: Vec<Track> = Vec::new(); |
| 206 | for path in &played_track_paths { | 211 | for path in &played_track_paths { |
| 207 | if let Some(track) = self.tracks.iter().find(|t| &t.path == path) { | 212 | if let Some(track) = self.tracks.iter().find(|t| &t.path == path) { |
| @@ -209,14 +214,18 @@ impl Queue { | |||
| 209 | } | 214 | } |
| 210 | } | 215 | } |
| 211 | 216 | ||
| 217 | eprintln!("DEBUG: kept {} played tracks", new_tracks.len()); | ||
| 218 | |||
| 212 | // Add remaining tracks from original in original order | 219 | // Add remaining tracks from original in original order |
| 213 | for orig_track in &self.original_tracks { | 220 | for (i, orig_track) in self.original_tracks.iter().enumerate() { |
| 214 | let is_played = played_track_paths.iter().any(|p| p == &orig_track.path); | 221 | let is_played = played_track_paths.iter().any(|p| p == &orig_track.path); |
| 215 | if !is_played { | 222 | if !is_played { |
| 223 | eprintln!("DEBUG: adding unplayed from original idx {}: {:?}", i, orig_track.path.file_name()); | ||
| 216 | new_tracks.push(orig_track.clone()); | 224 | new_tracks.push(orig_track.clone()); |
| 217 | } | 225 | } |
| 218 | } | 226 | } |
| 219 | 227 | ||
| 228 | eprintln!("DEBUG: final tracks.len={}", new_tracks.len()); | ||
| 220 | self.tracks = new_tracks; | 229 | self.tracks = new_tracks; |
| 221 | self.position = current_pos; | 230 | self.position = current_pos; |
| 222 | self.shuffled_indices.clear(); | 231 | self.shuffled_indices.clear(); |
