aboutsummaryrefslogtreecommitdiffstats
path: root/src/audio.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/audio.rs23
1 files changed, 23 insertions, 0 deletions
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 {
122 pub current_track: Arc<Mutex<Option<std::path::PathBuf>>>, 122 pub current_track: Arc<Mutex<Option<std::path::PathBuf>>>,
123 track_ended: Arc<AtomicBool>, 123 track_ended: Arc<AtomicBool>,
124 volume: Arc<Mutex<f32>>, 124 volume: Arc<Mutex<f32>>,
125 position: Arc<Mutex<f64>>,
125} 126}
126 127
127#[allow(clippy::new_without_default)] 128#[allow(clippy::new_without_default)]
@@ -138,6 +139,9 @@ impl AudioEngine {
138 let volume = Arc::new(Mutex::new(1.0f32)); 139 let volume = Arc::new(Mutex::new(1.0f32));
139 let volume_clone = Arc::clone(&volume); 140 let volume_clone = Arc::clone(&volume);
140 141
142 let position = Arc::new(Mutex::new(0.0));
143 let position_clone = Arc::clone(&position);
144
141 thread::spawn(move || { 145 thread::spawn(move || {
142 audio_thread( 146 audio_thread(
143 rx, 147 rx,
@@ -145,6 +149,7 @@ impl AudioEngine {
145 current_track_clone, 149 current_track_clone,
146 volume_clone, 150 volume_clone,
147 track_ended_clone, 151 track_ended_clone,
152 position_clone,
148 ); 153 );
149 }); 154 });
150 155
@@ -154,6 +159,7 @@ impl AudioEngine {
154 current_track, 159 current_track,
155 track_ended, 160 track_ended,
156 volume, 161 volume,
162 position,
157 } 163 }
158 } 164 }
159 165
@@ -199,6 +205,10 @@ impl AudioEngine {
199 pub fn poll_track_ended(&self) -> bool { 205 pub fn poll_track_ended(&self) -> bool {
200 self.track_ended.swap(false, Ordering::SeqCst) 206 self.track_ended.swap(false, Ordering::SeqCst)
201 } 207 }
208
209 pub fn position(&self) -> f64 {
210 self.position.lock().map(|p| *p).unwrap_or(0.0)
211 }
202} 212}
203 213
204struct AudioData { 214struct AudioData {
@@ -245,6 +255,7 @@ fn audio_thread(
245 current_track: Arc<Mutex<Option<std::path::PathBuf>>>, 255 current_track: Arc<Mutex<Option<std::path::PathBuf>>>,
246 volume: Arc<Mutex<f32>>, 256 volume: Arc<Mutex<f32>>,
247 track_ended: Arc<AtomicBool>, 257 track_ended: Arc<AtomicBool>,
258 position: Arc<Mutex<f64>>,
248) { 259) {
249 use cpal::traits::{DeviceTrait, HostTrait, StreamTrait}; 260 use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
250 261
@@ -282,6 +293,9 @@ fn audio_thread(
282 if let Ok(mut track) = current_track.lock() { 293 if let Ok(mut track) = current_track.lock() {
283 *track = Some(path.clone()); 294 *track = Some(path.clone());
284 } 295 }
296 if let Ok(mut pos) = position.lock() {
297 *pos = 0.0;
298 }
285 299
286 // Drop the current stream before creating a new one 300 // Drop the current stream before creating a new one
287 current_stream = None; 301 current_stream = None;
@@ -334,6 +348,7 @@ fn audio_thread(
334 let vol = Arc::clone(&volume); 348 let vol = Arc::clone(&volume);
335 let ended = Arc::clone(&track_ended); 349 let ended = Arc::clone(&track_ended);
336 let is_playing_clone = Arc::clone(&is_playing); 350 let is_playing_clone = Arc::clone(&is_playing);
351 let position_clone = Arc::clone(&position);
337 352
338 if let Ok(mut d) = audio_data.lock() { 353 if let Ok(mut d) = audio_data.lock() {
339 *d = Some(data); 354 *d = Some(data);
@@ -434,6 +449,14 @@ fn audio_thread(
434 *sample = 0.0; 449 *sample = 0.0;
435 } 450 }
436 451
452 // Track playback position
453 if offset > 0
454 && let Ok(mut pos) = position_clone.lock()
455 {
456 *pos += offset as f64
457 / (device_sample_rate as f64 * channels as f64);
458 }
459
437 // If no more data and offset is 0, track ended 460 // If no more data and offset is 0, track ended
438 if offset == 0 && state.sample_buffer.is_empty() { 461 if offset == 0 && state.sample_buffer.is_empty() {
439 ended.store(true, Ordering::SeqCst); 462 ended.store(true, Ordering::SeqCst);