use crate::fingerprinting::algorithm::SignatureGenerator;
use crate::fingerprinting::signature_format::DecodedSignature;
use crate::config::Config;
pub struct AudioProcessor {
signature_generator: SignatureGenerator,
sample_buffer: Vec<i16>,
samples_processed: usize,
target_sample_rate: u32,
config: Config,
}
impl AudioProcessor {
pub fn new() -> Self {
Self {
signature_generator: SignatureGenerator::new(),
sample_buffer: Vec::new(),
samples_processed: 0,
target_sample_rate: 16000, config: Config::default(),
}
}
pub fn with_config(config: Config) -> Self {
Self {
signature_generator: SignatureGenerator::new(),
sample_buffer: Vec::new(),
samples_processed: 0,
target_sample_rate: 16000, config,
}
}
pub fn process_samples(&mut self, samples: &[i16]) -> Result<Option<DecodedSignature>, Box<dyn std::error::Error>> {
self.sample_buffer.extend_from_slice(samples);
while self.sample_buffer.len() >= 128 {
let chunk: Vec<i16> = self.sample_buffer.drain(0..128).collect();
self.signature_generator.do_fft(&chunk, self.target_sample_rate);
self.samples_processed += 128;
let min_samples = (12.0 * self.target_sample_rate as f32) as usize;
if self.samples_processed >= min_samples {
if !self.config.quiet_mode {
eprintln!("Attempting recognition with {} samples", self.samples_processed);
}
let signature = self.signature_generator.get_signature();
let total_peaks: usize = signature.frequency_band_to_sound_peaks.values().map(|v| v.len()).sum();
if !self.config.quiet_mode {
eprintln!("Generated signature with {} total frequency peaks across {} bands",
total_peaks, signature.frequency_band_to_sound_peaks.len());
if total_peaks == 0 {
eprintln!("WARNING: No frequency peaks detected in audio - may be too quiet or not musical content");
}
}
self.reset();
return Ok(Some(signature));
}
}
Ok(None)
}
pub fn reset(&mut self) {
self.signature_generator = SignatureGenerator::new();
self.sample_buffer.clear();
self.samples_processed = 0;
}
pub fn get_progress(&self) -> f32 {
let min_samples = (12.0 * self.target_sample_rate as f32) as usize;
(self.samples_processed as f32 / min_samples as f32).min(1.0)
}
}
impl Default for AudioProcessor {
fn default() -> Self {
Self::new()
}
}