Skip to main content

voirs_sdk/audio/
buffer.rs

1//! Core audio buffer implementation and basic operations.
2
3use crate::types::AudioFormat;
4use serde::{Deserialize, Serialize};
5
6/// Audio buffer containing synthesized speech
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct AudioBuffer {
9    /// Audio samples as f32 values in range [-1.0, 1.0]
10    pub(super) samples: Vec<f32>,
11
12    /// Sample rate in Hz
13    pub(super) sample_rate: u32,
14
15    /// Number of audio channels (1=mono, 2=stereo)
16    pub(super) channels: u32,
17
18    /// Audio metadata
19    pub(super) metadata: AudioMetadata,
20}
21
22impl AudioBuffer {
23    /// Create new audio buffer
24    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    /// Create mono audio buffer
36    pub fn mono(samples: Vec<f32>, sample_rate: u32) -> Self {
37        Self::new(samples, sample_rate, 1)
38    }
39
40    /// Create stereo audio buffer
41    pub fn stereo(samples: Vec<f32>, sample_rate: u32) -> Self {
42        Self::new(samples, sample_rate, 2)
43    }
44
45    /// Get audio samples as slice
46    pub fn samples(&self) -> &[f32] {
47        &self.samples
48    }
49
50    /// Get mutable access to samples
51    pub fn samples_mut(&mut self) -> &mut [f32] {
52        &mut self.samples
53    }
54
55    /// Get sample rate in Hz
56    pub fn sample_rate(&self) -> u32 {
57        self.sample_rate
58    }
59
60    /// Get number of channels
61    pub fn channels(&self) -> u32 {
62        self.channels
63    }
64
65    /// Get duration in seconds
66    pub fn duration(&self) -> f32 {
67        self.metadata.duration
68    }
69
70    /// Get audio metadata
71    pub fn metadata(&self) -> &AudioMetadata {
72        &self.metadata
73    }
74
75    /// Get number of samples
76    pub fn len(&self) -> usize {
77        self.samples.len()
78    }
79
80    /// Check if buffer is empty
81    pub fn is_empty(&self) -> bool {
82        self.samples.is_empty()
83    }
84
85    /// Create silent audio buffer
86    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    /// Create audio buffer with sine wave (for testing)
93    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    /// Update metadata after modifications
112    pub(super) fn update_metadata(&mut self) {
113        self.metadata = AudioMetadata::from_samples(&self.samples, self.sample_rate, self.channels);
114    }
115
116    /// Create a new buffer with the same format but different samples
117    pub fn with_samples(&self, samples: Vec<f32>) -> Self {
118        Self::new(samples, self.sample_rate, self.channels)
119    }
120
121    /// Clone the buffer format without samples
122    pub fn clone_format(&self) -> BufferFormat {
123        BufferFormat {
124            sample_rate: self.sample_rate,
125            channels: self.channels,
126        }
127    }
128
129    /// Create buffer from format and samples
130    pub fn from_format(format: &BufferFormat, samples: Vec<f32>) -> Self {
131        Self::new(samples, format.sample_rate, format.channels)
132    }
133}
134
135/// Audio metadata
136#[derive(Debug, Clone, Serialize, Deserialize)]
137pub struct AudioMetadata {
138    /// Duration in seconds
139    pub duration: f32,
140
141    /// Peak amplitude (0.0 - 1.0)
142    pub peak_amplitude: f32,
143
144    /// RMS amplitude (0.0 - 1.0)
145    pub rms_amplitude: f32,
146
147    /// Dynamic range in dB
148    pub dynamic_range: f32,
149
150    /// Audio format
151    pub format: AudioFormat,
152}
153
154impl AudioMetadata {
155    /// Create metadata from audio samples
156    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        // Calculate dynamic range (simplified)
167        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, // Default format
179        }
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/// Buffer format specification
196#[derive(Debug, Clone, Copy, PartialEq, Eq)]
197pub struct BufferFormat {
198    /// Sample rate in Hz
199    pub sample_rate: u32,
200    /// Number of channels
201    pub channels: u32,
202}
203
204impl BufferFormat {
205    /// Create new buffer format
206    pub fn new(sample_rate: u32, channels: u32) -> Self {
207        Self {
208            sample_rate,
209            channels,
210        }
211    }
212
213    /// Mono format
214    pub fn mono(sample_rate: u32) -> Self {
215        Self::new(sample_rate, 1)
216    }
217
218    /// Stereo format
219    pub fn stereo(sample_rate: u32) -> Self {
220        Self::new(sample_rate, 2)
221    }
222
223    /// Check if formats are compatible
224    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); // 2 seconds * 22050 Hz * 2 channels
261        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}