ez_audi/samples_player/
exact_samples_player.rs1use std::sync::{Mutex, MutexGuard, Arc};
2
3use crate::{Device, traits::AudioMetadataTrait, cpal_abstraction, Error, modifiers::ModifierTrait};
4
5use cpal_abstraction::{Sample, Samples, SamplesTrait, IntermediateSampleType};
6
7use super::SamplesPlayerTrait;
8
9pub struct ExactSamplesPlayer<T: Sample> {
12 original_samples: Samples<T>,
13 modifiers: Vec<Box<dyn ModifierTrait>>,
14 samples_with_modifiers: Option<Arc<Mutex<Samples<T>>>>,
15 stream: Option<cpal_abstraction::Stream>,
16}
17
18impl<T: Sample> ExactSamplesPlayer<T>
19where IntermediateSampleType: cpal::FromSample<T> {
20 pub fn new(samples: Samples<T>) -> ExactSamplesPlayer<T> {
22 Self {
23 original_samples: samples,
24 modifiers: Vec::new(),
25 samples_with_modifiers: None,
26 stream: None,
27 }
28 }
29
30 fn aquire_samples_with_modifiers_mutex_guard(&self) -> Option<MutexGuard<Samples<T>>> {
31 let modified_samples_mutex = match &self.samples_with_modifiers {
32 Some(m) => m,
33 None => return None,
34 };
35
36 let mutex_lock = modified_samples_mutex.lock();
37 match mutex_lock {
38 Ok(l) => Some(l),
39 Err(_) => None,
41 }
42 }
43
44 fn change_samples_with_modifiers(&mut self, samples: Samples<T>) {
45 let mutex_guard_option = self.aquire_samples_with_modifiers_mutex_guard();
46
47 if let Some(mut guard) = mutex_guard_option {
48 *guard = samples;
49 } else {
50 drop(mutex_guard_option);
52 self.samples_with_modifiers = Some(Arc::new(Mutex::new(samples)))
53 }
54 }
55
56 fn apply_modifiers(&mut self) {
58 let mut modified_samples = self.original_samples.clone().into_generic_representation_samples();
60 for modifier in &self.modifiers {
61 modified_samples = modifier.modify(modified_samples);
62 }
63
64 let t_samples = modified_samples.into_t_samples();
65
66 self.change_samples_with_modifiers(t_samples);
67 }
68
69 fn set_stream(&mut self, stream: cpal_abstraction::Stream) {
70 self.apply_modifiers();
71
72 self.stream = Some(stream);
73 }
74}
75
76impl<T: Sample> SamplesPlayerTrait for ExactSamplesPlayer<T>
77where IntermediateSampleType: cpal::FromSample<T> {
78 fn metadata(&self) -> Box<dyn AudioMetadataTrait> {
79 Box::new(self.original_samples.metadata.clone())
80 }
81
82 fn add_modifier(&mut self, modifier: Box<dyn ModifierTrait>) {
83 self.modifiers.push(modifier);
84
85 self.apply_modifiers();
86 }
87
88 fn clear_modifiers(&mut self) {
89 self.modifiers = Vec::new();
90
91 self.apply_modifiers();
92 }
93
94 fn start(&self) -> Error<()> {
95 let stream = match &self.stream {
96 Some(s) => s,
97 None => return Ok(()), };
99
100 stream.start()
101 }
102
103 fn stop(&self) -> Error<()> {
104 let stream = match &self.stream {
105 Some(s) => s,
106 None => return Ok(()), };
108
109 stream.stop()
110 }
111
112 fn play_on_device(&mut self, device: Device) -> Error<()> {
113 self.apply_modifiers();
115
116 let samples_arc = self.samples_with_modifiers
117 .as_ref()
118 .expect("no samples with modifiers");
119 let samples_arc = Arc::clone(samples_arc);
120
121 let stream = device.create_stream(&self.original_samples.metadata,
122 samples_arc)?;
123
124 stream.start()?;
126
127 self.set_stream(stream);
128
129 Ok(())
130 }
131}