1use rodio::buffer::SamplesBuffer;
2use rodio::{OutputStream, Sink};
3use std::sync::atomic::{AtomicBool, Ordering};
4use std::sync::{Arc, Mutex};
5use std::thread;
6use std::time::Duration;
7
8use crate::effects::effects::clone_samples_buffer;
9use crate::prot::Prot;
10use crate::reporter::{Report, Reporter};
11use crate::timer;
12use crate::{info::Info, player_engine::PlayerEngine};
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum PlayerState {
16 Init,
17 Resuming,
18 Playing,
19 Pausing,
20 Paused,
21 Stopping,
22 Stopped,
23 Finished,
24}
25
26#[derive(Clone)]
27pub struct Player {
28 pub info: Info,
29 pub finished_tracks: Arc<Mutex<Vec<i32>>>,
30 pub ts: Arc<Mutex<f64>>,
31 state: Arc<Mutex<PlayerState>>,
32 abort: Arc<AtomicBool>,
33 playback_thread_exists: Arc<AtomicBool>,
34 duration: Arc<Mutex<f64>>,
35 prot: Arc<Mutex<Prot>>,
36 audio_heard: Arc<AtomicBool>,
37 volume: Arc<Mutex<f32>>,
38 sink: Arc<Mutex<Sink>>,
39 audition_source: Arc<Mutex<Option<SamplesBuffer<f32>>>>,
40 reporter: Option<Arc<Mutex<Reporter>>>,
41}
42
43impl Player {
44 pub fn new(file_path: &String) -> Self {
45 let this = Self::new_from_path_or_paths(Some(file_path), None);
46 this
47 }
48
49 pub fn new_from_file_paths(file_paths: &Vec<Vec<String>>) -> Self {
50 let this = Self::new_from_path_or_paths(None, Some(file_paths));
51 this
52 }
53
54 pub fn new_from_path_or_paths(path: Option<&String>, paths: Option<&Vec<Vec<String>>>) -> Self {
55 let (prot, info) = match path {
56 Some(path) => {
57 let prot = Arc::new(Mutex::new(Prot::new(path)));
58 let info = Info::new(path.clone());
59 (prot, info)
60 }
61 None => {
62 let prot = Arc::new(Mutex::new(Prot::new_from_file_paths(paths.unwrap())));
63 let locked_prot = prot.lock().unwrap();
64 let info = Info::new_from_file_paths(locked_prot.get_file_paths_dictionary());
65 drop(locked_prot);
66 (prot, info)
67 }
68 };
69
70 let (_stream, stream_handle) = OutputStream::try_default().unwrap();
71 let sink: Arc<Mutex<Sink>> = Arc::new(Mutex::new(Sink::try_new(&stream_handle).unwrap()));
72 let (_stream, audition_stream_handle) = OutputStream::try_default().unwrap();
73 let audition_sink = Arc::new(Mutex::new(Sink::try_new(&audition_stream_handle).unwrap()));
74
75 let mut this = Self {
76 info,
77 finished_tracks: Arc::new(Mutex::new(Vec::new())),
78 state: Arc::new(Mutex::new(PlayerState::Stopped)),
79 abort: Arc::new(AtomicBool::new(false)),
80 ts: Arc::new(Mutex::new(0.0)),
81 playback_thread_exists: Arc::new(AtomicBool::new(true)),
82 duration: Arc::new(Mutex::new(0.0)),
83 audio_heard: Arc::new(AtomicBool::new(false)),
84 volume: Arc::new(Mutex::new(0.8)),
85 sink,
86 audition_source: Arc::new(Mutex::new(None)),
87 prot,
88 reporter: None,
89 };
90
91 this.initialize_thread(None);
92
93 this
94 }
95
96 fn audition(&self, length: Duration) {
97 let audition_source_mutex = self.audition_source.clone();
98
99 thread::spawn(move || {
101 while audition_source_mutex.lock().unwrap().is_none() {
103 thread::sleep(Duration::from_millis(10));
104 }
105
106 let audition_source_option = audition_source_mutex.lock().unwrap().take();
107 let audition_source = audition_source_option.unwrap();
108
109 let (_stream, audition_stream_handle) = OutputStream::try_default().unwrap();
110 let audition_sink = Sink::try_new(&audition_stream_handle).unwrap();
111 audition_sink.pause();
112 audition_sink.set_volume(0.8);
113 audition_sink.append(audition_source);
114 audition_sink.play();
115 thread::sleep(length);
116 audition_sink.pause();
117 });
118 }
119
120 fn initialize_thread(&mut self, ts: Option<f64>) {
121 let mut finished_tracks = self.finished_tracks.lock().unwrap();
123 finished_tracks.clear();
124 drop(finished_tracks);
125
126 self.abort.store(false, Ordering::SeqCst);
128 self.playback_thread_exists.store(true, Ordering::SeqCst);
129
130 let play_state = self.state.clone();
132 let abort = self.abort.clone();
133 let playback_thread_exists = self.playback_thread_exists.clone();
134 let time_passed = self.ts.clone();
135
136 let duration = self.duration.clone();
137 let prot = self.prot.clone();
138
139 let audio_heard = self.audio_heard.clone();
140 let volume = self.volume.clone();
141 let sink_mutex = self.sink.clone();
142 let audition_source_mutex = self.audition_source.clone();
143 let channels = 1.0 * self.info.channels as f64;
144
145 audio_heard.store(false, Ordering::Relaxed);
146
147 let mut audition_source = audition_source_mutex.lock().unwrap();
149 *audition_source = None;
150 drop(audition_source);
151
152 thread::spawn(move || {
154 playback_thread_exists.store(true, Ordering::Relaxed);
158
159 let start_time = match ts {
163 Some(ts) => ts,
164 None => 0.0,
165 };
166 let mut engine = PlayerEngine::new(prot, Some(abort.clone()), start_time);
167 let (_stream, stream_handle) = OutputStream::try_default().unwrap();
168 let mut sink = sink_mutex.lock().unwrap();
171 *sink = Sink::try_new(&stream_handle).unwrap();
172 sink.pause();
173 sink.set_volume(*volume.lock().unwrap());
174 drop(sink);
175
176 let mut duration = duration.lock().unwrap();
180 *duration = engine.get_duration();
181 drop(duration);
182
183 let chunk_lengths = Arc::new(Mutex::new(Vec::new()));
187 let mut time_passed_unlocked = time_passed.lock().unwrap();
188 *time_passed_unlocked = start_time;
189 drop(time_passed_unlocked);
190
191 let pause_sink = |sink: &Sink, fade_length_out_seconds: f32| {
192 let timestamp = *time_passed.lock().unwrap();
193
194 let fade_increments = sink.volume() / (fade_length_out_seconds * 100.0);
195 while sink.volume() > 0.0 && timestamp != start_time {
197 sink.set_volume(sink.volume() - fade_increments);
198 thread::sleep(Duration::from_millis(10));
199 }
200 sink.pause();
201 };
202
203 let resume_sink = |sink: &Sink, fade_length_in_seconds: f32| {
204 let volume = *volume.lock().unwrap();
205 let fade_increments = (volume - sink.volume()) / (fade_length_in_seconds * 100.0);
206 sink.play();
208 while sink.volume() < volume {
209 sink.set_volume(sink.volume() + fade_increments);
210 thread::sleep(Duration::from_millis(5));
211 }
212 };
213
214 let check_details = || {
223 if abort.load(Ordering::SeqCst) {
224 let sink = sink_mutex.lock().unwrap();
225 pause_sink(&sink, 0.1);
226 sink.clear();
227 drop(sink);
228
229 return false;
230 }
231
232 let sink = sink_mutex.lock().unwrap();
233 let state = play_state.lock().unwrap().clone();
234 if state == PlayerState::Pausing {
235 pause_sink(&sink, 0.1);
236 play_state.lock().unwrap().clone_from(&PlayerState::Paused);
237 }
238 if state == PlayerState::Resuming {
239 resume_sink(&sink, 0.1);
240 play_state.lock().unwrap().clone_from(&PlayerState::Playing);
241 }
242 drop(sink);
243
244 true
245 };
246
247 let time_chunks_mutex = Arc::new(Mutex::new(start_time));
251 let timer_mut = Arc::new(Mutex::new(timer::Timer::new()));
252 let mut timer = timer_mut.lock().unwrap();
253 timer.start();
254 drop(timer);
255
256 let update_chunk_lengths = || {
257 if abort.load(Ordering::SeqCst) {
258 return;
259 }
260
261 let mut chunk_lengths = chunk_lengths.lock().unwrap();
262 let mut time_passed_unlocked = time_passed.lock().unwrap();
263 let mut time_chunks_passed = time_chunks_mutex.lock().unwrap();
264 let mut timer = timer_mut.lock().unwrap();
265 let sink = sink_mutex.lock().unwrap();
269 let chunks_played = chunk_lengths.len() - sink.len();
270
271 for _ in 0..chunks_played {
272 timer.reset();
273 timer.start();
274 *time_chunks_passed += chunk_lengths.remove(0);
275 }
276
277 if sink.is_paused() {
278 timer.pause();
279 } else {
280 timer.un_pause();
281 }
282
283 *time_passed_unlocked = *time_chunks_passed + timer.get_time().as_secs_f64();
284
285 drop(sink);
286 drop(chunk_lengths);
287 drop(time_passed_unlocked);
288 drop(time_chunks_passed);
289 drop(timer);
290 };
291
292 let update_sink = |(mixer, length_in_seconds): (SamplesBuffer<f32>, f64)| {
296 audio_heard.store(true, Ordering::Relaxed);
297
298 let mut audition_source = audition_source_mutex.lock().unwrap();
299 let sink = sink_mutex.lock().unwrap();
300 let mut chunk_lengths = chunk_lengths.lock().unwrap();
301
302 let total_time = chunk_lengths.iter().sum::<f64>();
303
304 if audition_source.is_none() {
306 let (mixer_clone, mixer) = clone_samples_buffer(mixer);
307 *audition_source = Some(mixer_clone);
308 drop(audition_source);
309 sink.append(mixer);
310 } else {
311 sink.append(mixer);
312 }
313 drop(sink);
314
315 chunk_lengths.push(length_in_seconds);
316 drop(chunk_lengths);
317
318 update_chunk_lengths();
319 check_details();
320 };
321
322 engine.reception_loop(&update_sink);
323
324 loop {
328 update_chunk_lengths();
329 if !check_details() {
330 break;
331 }
332
333 let sink = sink_mutex.lock().unwrap();
334 let sink_empty = sink.empty();
335 drop(sink);
336 if sink_empty && engine.finished_buffering() {
338 break;
339 }
340
341 thread::sleep(Duration::from_millis(10));
342 }
343
344 playback_thread_exists.store(false, Ordering::Relaxed);
348 });
349 }
350
351 pub fn play_at(&mut self, ts: f64) {
352 let mut timestamp = self.ts.lock().unwrap();
353 *timestamp = ts;
354 drop(timestamp);
355
356 self.kill_current();
357 self.initialize_thread(Some(ts));
359
360 self.resume();
361
362 while !self.audio_heard.load(Ordering::Relaxed) {
364 thread::sleep(Duration::from_millis(10));
365 }
366 }
367
368 pub fn play(&mut self) {
369 let thread_exists = self.playback_thread_exists.load(Ordering::SeqCst);
370 if !thread_exists {
373 self.initialize_thread(None);
374 }
375
376 self.resume();
377
378 while !self.audio_heard.load(Ordering::Relaxed) {
380 thread::sleep(Duration::from_millis(10));
381 }
382 }
383
384 pub fn pause(&self) {
385 self.state.lock().unwrap().clone_from(&PlayerState::Pausing);
386 }
387
388 pub fn resume(&self) {
389 self.state
390 .lock()
391 .unwrap()
392 .clone_from(&PlayerState::Resuming);
393 }
394
395 pub fn kill_current(&self) {
396 self.state
397 .lock()
398 .unwrap()
399 .clone_from(&PlayerState::Stopping);
400 self.abort.store(true, Ordering::SeqCst);
401
402 while !self.thread_finished() {
403 thread::sleep(Duration::from_millis(10));
404 }
405
406 self.state.lock().unwrap().clone_from(&PlayerState::Stopped);
407 }
408
409 pub fn stop(&self) {
410 self.kill_current();
411 self.ts.lock().unwrap().clone_from(&0.0);
412 }
413
414 pub fn is_playing(&self) -> bool {
415 let state = self.state.lock().unwrap();
416 *state == PlayerState::Playing
417 }
418
419 pub fn is_paused(&self) -> bool {
420 let state = self.state.lock().unwrap();
421 *state == PlayerState::Paused
422 }
423
424 pub fn get_time(&self) -> f64 {
425 let ts = self.ts.lock().unwrap();
426 *ts
427 }
428
429 fn thread_finished(&self) -> bool {
430 let playback_thread_exists = self.playback_thread_exists.load(Ordering::SeqCst);
431 !playback_thread_exists
432 }
433
434 pub fn is_finished(&self) -> bool {
435 self.thread_finished()
436 }
439
440 pub fn sleep_until_end(&self) {
441 loop {
442 if self.thread_finished() {
443 break;
444 }
445 thread::sleep(Duration::from_millis(100));
446 }
447 }
448
449 pub fn get_duration(&self) -> f64 {
450 let duration = self.duration.lock().unwrap();
451 *duration
452 }
453
454 pub fn seek(&mut self, ts: f64) {
455 let mut timestamp = self.ts.lock().unwrap();
456 *timestamp = ts;
457 drop(timestamp);
458
459 let state = self.state.lock().unwrap().clone();
460
461 self.kill_current();
462 self.state.lock().unwrap().clone_from(&state);
463 self.initialize_thread(Some(ts));
464
465 match state {
466 PlayerState::Playing => self.resume(),
467 PlayerState::Paused => {
468 self.audition(Duration::from_millis(100));
469 }
470 _ => {}
471 }
472 }
473
474 pub fn refresh_tracks(&mut self) {
475 let mut prot = self.prot.lock().unwrap();
476 prot.refresh_tracks();
477 drop(prot);
478
479 if self.thread_finished() {
481 return;
482 }
483
484 let ts = self.get_time();
487 self.seek(ts);
488
489 if self.is_playing() {
491 self.resume();
492 }
493
494 while !self.audio_heard.load(Ordering::Relaxed) {
496 thread::sleep(Duration::from_millis(10));
497 }
498 }
499
500 pub fn shuffle(&mut self) {
501 self.refresh_tracks();
502 }
503
504 pub fn set_volume(&mut self, new_volume: f32) {
505 let sink = self.sink.lock().unwrap();
506 sink.set_volume(new_volume);
507 drop(sink);
508
509 let mut volume = self.volume.lock().unwrap();
510 *volume = new_volume;
511 drop(volume);
512 }
513
514 pub fn get_volume(&self) -> f32 {
515 *self.volume.lock().unwrap()
516 }
517
518 pub fn get_ids(&self) -> Vec<String> {
519 let prot = self.prot.lock().unwrap();
520
521 return prot.get_ids();
522 }
523
524 pub fn set_reporting(
525 &mut self,
526 reporting: Arc<Mutex<dyn Fn(Report) + Send>>,
527 reporting_interval: Duration,
528 ) {
529 if self.reporter.is_some() {
530 self.reporter.as_ref().unwrap().lock().unwrap().stop();
531 }
532
533 let reporter = Arc::new(Mutex::new(Reporter::new(
534 Arc::new(Mutex::new(self.clone())),
535 reporting,
536 reporting_interval,
537 )));
538
539 reporter.lock().unwrap().start();
540
541 self.reporter = Some(reporter);
542 }
543}