From 45a1728ea4a3812120728562084fd416b35b074c Mon Sep 17 00:00:00 2001 From: salmonik Date: Sun, 7 Jun 2026 21:19:46 +0300 Subject: Add lyrics support --- src/audio.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src/audio.rs') diff --git a/src/audio.rs b/src/audio.rs index 6da47c3..f8eba04 100644 --- a/src/audio.rs +++ b/src/audio.rs @@ -122,6 +122,7 @@ pub struct AudioEngine { pub current_track: Arc>>, track_ended: Arc, volume: Arc>, + position: Arc>, } #[allow(clippy::new_without_default)] @@ -138,6 +139,9 @@ impl AudioEngine { let volume = Arc::new(Mutex::new(1.0f32)); let volume_clone = Arc::clone(&volume); + let position = Arc::new(Mutex::new(0.0)); + let position_clone = Arc::clone(&position); + thread::spawn(move || { audio_thread( rx, @@ -145,6 +149,7 @@ impl AudioEngine { current_track_clone, volume_clone, track_ended_clone, + position_clone, ); }); @@ -154,6 +159,7 @@ impl AudioEngine { current_track, track_ended, volume, + position, } } @@ -199,6 +205,10 @@ impl AudioEngine { pub fn poll_track_ended(&self) -> bool { self.track_ended.swap(false, Ordering::SeqCst) } + + pub fn position(&self) -> f64 { + self.position.lock().map(|p| *p).unwrap_or(0.0) + } } struct AudioData { @@ -245,6 +255,7 @@ fn audio_thread( current_track: Arc>>, volume: Arc>, track_ended: Arc, + position: Arc>, ) { use cpal::traits::{DeviceTrait, HostTrait, StreamTrait}; @@ -282,6 +293,9 @@ fn audio_thread( if let Ok(mut track) = current_track.lock() { *track = Some(path.clone()); } + if let Ok(mut pos) = position.lock() { + *pos = 0.0; + } // Drop the current stream before creating a new one current_stream = None; @@ -334,6 +348,7 @@ fn audio_thread( let vol = Arc::clone(&volume); let ended = Arc::clone(&track_ended); let is_playing_clone = Arc::clone(&is_playing); + let position_clone = Arc::clone(&position); if let Ok(mut d) = audio_data.lock() { *d = Some(data); @@ -434,6 +449,14 @@ fn audio_thread( *sample = 0.0; } + // Track playback position + if offset > 0 + && let Ok(mut pos) = position_clone.lock() + { + *pos += offset as f64 + / (device_sample_rate as f64 * channels as f64); + } + // If no more data and offset is 0, track ended if offset == 0 && state.sample_buffer.is_empty() { ended.store(true, Ordering::SeqCst); -- cgit v1.2.3