ez_audi/cpal_abstraction/samples/
samples.rs1use cpal::{self, Sample as CpalSampleTrait};
2
3use crate::{traits::AudioMetadataTrait, audio_codecs::AudioCodec};
4
5use super::{SampleType, Sample, IntermediateSampleType};
6
7#[derive(Debug, Clone)]
8pub struct Samples<T: Sample> {
10 pub samples: Vec<T>,
17 pub metadata: SamplesMetadata,
20}
21
22impl<T: Sample> Samples<T> {
23 pub fn new(samples: Vec<T>, metadata: SamplesMetadata) -> Samples<T> {
25 Samples {
26 samples,
27 metadata,
28 }
29 }
30
31 fn update_sample_type(&mut self) {
33 self.metadata.sample_type = match self.samples.get(0) {
34 Some(t) => (*t).into(),
35 None => self.metadata.sample_type.clone(),
36 }
37 }
38}
39
40impl Samples<IntermediateSampleType> {
41 pub fn into_t_samples<T: Sample + cpal::FromSample<IntermediateSampleType>>(self) -> Samples<T> {
43 let samples = self.samples.into_iter()
44 .map(|s| s.to_sample::<T>())
45 .collect();
46
47 let metadata = self.metadata.clone();
48 let mut samples = Samples::new(samples, metadata);
49
50 samples.update_sample_type();
51
52 samples
53 }
54}
55
56pub trait SamplesTrait {
58 fn into_generic_representation_samples(self) -> Samples<IntermediateSampleType>;
60
61 fn generic_representation_samples(&self) -> Samples<IntermediateSampleType>;
63
64 fn metadata(&self) -> Box<dyn AudioMetadataTrait>;
66}
67
68impl<T: Sample> SamplesTrait for Samples<T>
69where IntermediateSampleType: cpal::FromSample<T> {
70 fn into_generic_representation_samples(self) -> Samples<IntermediateSampleType> {
71 let f32_samples = self.samples.into_iter().map(|s| s.to_sample()).collect();
72
73 let mut samples = Samples::new(f32_samples, self.metadata.clone());
74 samples.update_sample_type();
75
76 samples
77 }
78
79 fn generic_representation_samples(&self) -> Samples<IntermediateSampleType> {
80 let f32_samples = self.samples.clone().into_iter().map(|s| s.to_sample()).collect();
81
82 let mut samples = Samples::new(f32_samples, self.metadata.clone());
83 samples.update_sample_type();
84
85 samples
86 }
87
88 fn metadata(&self) -> Box<dyn AudioMetadataTrait> {
89 Box::new(self.metadata.clone())
90 }
91}
92
93#[derive(Debug, Clone)]
94pub struct SamplesMetadata {
96 pub channels: u16,
98 pub sample_rate: u32,
100 pub sample_type: SampleType,
102}
103
104impl SamplesMetadata {
105 pub fn new(channels: u16, sample_rate: u32, sample_type: SampleType) -> SamplesMetadata {
106 SamplesMetadata {
107 channels,
108 sample_rate,
109 sample_type,
110 }
111 }
112}
113
114impl AudioMetadataTrait for SamplesMetadata {
115 fn file_path(&self) -> Option<String> {
116 None
117 }
118
119 fn audio_codec(&self) -> crate::audio_codecs::AudioCodec {
121 AudioCodec::LPcm
122 }
123
124 fn channels(&self) -> u32 {
125 self.channels as u32
126 }
127
128 fn sample_rate(&self) -> u32 {
129 self.sample_rate
130 }
131
132 fn sample_type(&self) -> Option<SampleType> {
133 Some(self.sample_type.clone())
134 }
135}
136
137impl From<&SamplesMetadata> for cpal::SupportedStreamConfig {
138 fn from(value: &SamplesMetadata) -> Self {
139 let channels = value.channels;
140 let sample_rate = cpal::SampleRate(value.sample_rate);
141 let sample_type = value.sample_type.clone().into();
142
143 cpal::SupportedStreamConfig::new(channels, sample_rate, cpal::SupportedBufferSize::Unknown, sample_type)
144 }
145}