use std::{
sync::{atomic::Ordering, Arc, Mutex},
time::Duration,
};
use tracing::error;
use crate::audio_state::RecordingState;
pub const SAMPLE_RATE: u32 = 16000;
pub const BUFFER_SIZE: u32 = 1024;
pub const CHANNELS: u16 = 1;
pub const CHUNK_DURATION_MS: u64 = 5000;
pub const CHUNK_SIZE: usize =
(SAMPLE_RATE as usize * CHANNELS as usize) * (CHUNK_DURATION_MS as usize) / 1000;
#[derive(Debug)]
pub struct AudioBuffer {
samples: Vec<f32>,
recording_state: RecordingState,
required_samples: usize,
}
impl AudioBuffer {
pub fn new(
recording_state: RecordingState,
sample_rate: u32,
min_chunk_duration: Duration,
) -> Self {
let required_samples = (sample_rate as f32 * min_chunk_duration.as_secs_f32()) as usize;
Self {
samples: Vec::with_capacity(required_samples * 2),
recording_state,
required_samples,
}
}
}
pub fn resample_audio(input: &[f32], source_rate: u32, target_rate: u32) -> Vec<f32> {
use rubato::{Resampler, SincFixedIn};
let mut resampler = SincFixedIn::<f32>::new(
target_rate as f64 / source_rate as f64,
2.0,
rubato::SincInterpolationParameters {
sinc_len: 256,
f_cutoff: 0.95,
oversampling_factor: 128,
window: rubato::WindowFunction::BlackmanHarris2,
interpolation: rubato::SincInterpolationType::Linear,
},
input.len(),
1,
)
.expect("Failed to create resampler");
let output = resampler
.process(&[input.to_vec()], None)
.expect("Resampling failed");
output.into_iter().flatten().collect()
}
pub fn audio_to_mono(audio: &[f32], channels: u16) -> Vec<f32> {
if channels == 0 {
return Vec::new(); }
if channels == 1 {
return audio.to_vec(); }
let frame_count = audio.len() / channels as usize;
let mut mono_samples = Vec::with_capacity(frame_count);
for frame_index in 0..frame_count {
let start = frame_index * channels as usize;
let end = start + channels as usize;
let chunk = &audio[start..end.min(audio.len())];
let sum: f32 = chunk.iter().sum();
let mono_sample = sum / (channels as f32);
mono_samples.push(mono_sample);
}
mono_samples
}