1use crate::types::AudioFormat;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct AudioBuffer {
9 pub(super) samples: Vec<f32>,
11
12 pub(super) sample_rate: u32,
14
15 pub(super) channels: u32,
17
18 pub(super) metadata: AudioMetadata,
20}
21
22impl AudioBuffer {
23 pub fn new(samples: Vec<f32>, sample_rate: u32, channels: u32) -> Self {
25 let metadata = AudioMetadata::from_samples(&samples, sample_rate, channels);
26
27 Self {
28 samples,
29 sample_rate,
30 channels,
31 metadata,
32 }
33 }
34
35 pub fn mono(samples: Vec<f32>, sample_rate: u32) -> Self {
37 Self::new(samples, sample_rate, 1)
38 }
39
40 pub fn stereo(samples: Vec<f32>, sample_rate: u32) -> Self {
42 Self::new(samples, sample_rate, 2)
43 }
44
45 pub fn samples(&self) -> &[f32] {
47 &self.samples
48 }
49
50 pub fn samples_mut(&mut self) -> &mut [f32] {
52 &mut self.samples
53 }
54
55 pub fn sample_rate(&self) -> u32 {
57 self.sample_rate
58 }
59
60 pub fn channels(&self) -> u32 {
62 self.channels
63 }
64
65 pub fn duration(&self) -> f32 {
67 self.metadata.duration
68 }
69
70 pub fn metadata(&self) -> &AudioMetadata {
72 &self.metadata
73 }
74
75 pub fn len(&self) -> usize {
77 self.samples.len()
78 }
79
80 pub fn is_empty(&self) -> bool {
82 self.samples.is_empty()
83 }
84
85 pub fn silence(duration_seconds: f32, sample_rate: u32, channels: u32) -> Self {
87 let sample_count = (duration_seconds * sample_rate as f32 * channels as f32) as usize;
88 let samples = vec![0.0; sample_count];
89 Self::new(samples, sample_rate, channels)
90 }
91
92 pub fn sine_wave(
94 frequency: f32,
95 duration_seconds: f32,
96 sample_rate: u32,
97 amplitude: f32,
98 ) -> Self {
99 let sample_count = (duration_seconds * sample_rate as f32) as usize;
100 let mut samples = Vec::with_capacity(sample_count);
101
102 for i in 0..sample_count {
103 let t = i as f32 / sample_rate as f32;
104 let sample = amplitude * (2.0 * std::f32::consts::PI * frequency * t).sin();
105 samples.push(sample);
106 }
107
108 Self::mono(samples, sample_rate)
109 }
110
111 pub(super) fn update_metadata(&mut self) {
113 self.metadata = AudioMetadata::from_samples(&self.samples, self.sample_rate, self.channels);
114 }
115
116 pub fn with_samples(&self, samples: Vec<f32>) -> Self {
118 Self::new(samples, self.sample_rate, self.channels)
119 }
120
121 pub fn clone_format(&self) -> BufferFormat {
123 BufferFormat {
124 sample_rate: self.sample_rate,
125 channels: self.channels,
126 }
127 }
128
129 pub fn from_format(format: &BufferFormat, samples: Vec<f32>) -> Self {
131 Self::new(samples, format.sample_rate, format.channels)
132 }
133}
134
135#[derive(Debug, Clone, Serialize, Deserialize)]
137pub struct AudioMetadata {
138 pub duration: f32,
140
141 pub peak_amplitude: f32,
143
144 pub rms_amplitude: f32,
146
147 pub dynamic_range: f32,
149
150 pub format: AudioFormat,
152}
153
154impl AudioMetadata {
155 pub fn from_samples(samples: &[f32], sample_rate: u32, channels: u32) -> Self {
157 let duration = samples.len() as f32 / (sample_rate * channels) as f32;
158 let peak_amplitude = samples.iter().map(|&s| s.abs()).fold(0.0, f32::max);
159 let sum_squares: f32 = samples.iter().map(|&s| s * s).sum();
160 let rms_amplitude = if samples.is_empty() {
161 0.0
162 } else {
163 (sum_squares / samples.len() as f32).sqrt()
164 };
165
166 let dynamic_range = if rms_amplitude > 0.0 {
168 20.0 * (peak_amplitude / rms_amplitude).log10()
169 } else {
170 0.0
171 };
172
173 Self {
174 duration,
175 peak_amplitude,
176 rms_amplitude,
177 dynamic_range,
178 format: AudioFormat::Wav, }
180 }
181}
182
183impl Default for AudioMetadata {
184 fn default() -> Self {
185 Self {
186 duration: 0.0,
187 peak_amplitude: 0.0,
188 rms_amplitude: 0.0,
189 dynamic_range: 0.0,
190 format: AudioFormat::Wav,
191 }
192 }
193}
194
195#[derive(Debug, Clone, Copy, PartialEq, Eq)]
197pub struct BufferFormat {
198 pub sample_rate: u32,
200 pub channels: u32,
202}
203
204impl BufferFormat {
205 pub fn new(sample_rate: u32, channels: u32) -> Self {
207 Self {
208 sample_rate,
209 channels,
210 }
211 }
212
213 pub fn mono(sample_rate: u32) -> Self {
215 Self::new(sample_rate, 1)
216 }
217
218 pub fn stereo(sample_rate: u32) -> Self {
220 Self::new(sample_rate, 2)
221 }
222
223 pub fn is_compatible(&self, other: &BufferFormat) -> bool {
225 self.sample_rate == other.sample_rate && self.channels == other.channels
226 }
227}
228
229#[cfg(test)]
230mod tests {
231 use super::*;
232
233 #[test]
234 fn test_audio_buffer_creation() {
235 let samples = vec![0.1, 0.2, 0.3, 0.4];
236 let buffer = AudioBuffer::mono(samples.clone(), 44100);
237
238 assert_eq!(buffer.samples(), &samples);
239 assert_eq!(buffer.sample_rate(), 44100);
240 assert_eq!(buffer.channels(), 1);
241 assert!(buffer.duration() > 0.0);
242 }
243
244 #[test]
245 fn test_sine_wave_generation() {
246 let buffer = AudioBuffer::sine_wave(440.0, 1.0, 44100, 0.5);
247
248 assert_eq!(buffer.sample_rate(), 44100);
249 assert_eq!(buffer.channels(), 1);
250 assert_eq!(buffer.len(), 44100);
251 assert!((buffer.duration() - 1.0).abs() < 0.01);
252 }
253
254 #[test]
255 fn test_silence_generation() {
256 let buffer = AudioBuffer::silence(2.0, 22050, 2);
257
258 assert_eq!(buffer.sample_rate(), 22050);
259 assert_eq!(buffer.channels(), 2);
260 assert_eq!(buffer.len(), 88200); assert!(buffer.samples().iter().all(|&s| s == 0.0));
262 }
263
264 #[test]
265 fn test_metadata_calculation() {
266 let samples = vec![0.5, -0.3, 0.8, -0.1];
267 let buffer = AudioBuffer::mono(samples, 44100);
268
269 let metadata = buffer.metadata();
270 assert_eq!(metadata.peak_amplitude, 0.8);
271 assert!(metadata.rms_amplitude > 0.0);
272 assert!(metadata.duration > 0.0);
273 }
274
275 #[test]
276 fn test_buffer_format() {
277 let format = BufferFormat::mono(44100);
278 assert_eq!(format.sample_rate, 44100);
279 assert_eq!(format.channels, 1);
280
281 let stereo_format = BufferFormat::stereo(22050);
282 assert_eq!(stereo_format.sample_rate, 22050);
283 assert_eq!(stereo_format.channels, 2);
284
285 assert!(!format.is_compatible(&stereo_format));
286 }
287
288 #[test]
289 fn test_buffer_cloning() {
290 let samples = vec![0.1, 0.2, 0.3];
291 let buffer = AudioBuffer::mono(samples.clone(), 44100);
292
293 let format = buffer.clone_format();
294 let new_buffer = AudioBuffer::from_format(&format, vec![0.4, 0.5, 0.6]);
295
296 assert_eq!(new_buffer.sample_rate(), 44100);
297 assert_eq!(new_buffer.channels(), 1);
298 assert_eq!(new_buffer.samples(), &[0.4, 0.5, 0.6]);
299 }
300}