use crate::error::{Error, Result};
const QUEUE_SIZE: usize = 4096;
pub(crate) const DWT_LEVELS: usize = 4;
const AUDIO_BUFFER_SIZE: u32 = 256;
const DWT_WINDOW_SIZE: usize = 65536;
pub(crate) const TARGET_SAMPLING_RATE: f64 = 22050.0;
const MIN_BPM: f32 = 40.0;
const MAX_BPM: f32 = 240.0;
#[derive(Clone, Debug, Copy, bon::Builder)]
pub struct AnalyzerConfig {
#[builder(default = MIN_BPM)]
min_bpm: f32,
#[builder(default = MAX_BPM)]
max_bpm: f32,
#[builder(default = DWT_WINDOW_SIZE)]
window_size: usize,
#[builder(default = QUEUE_SIZE)]
queue_size: usize,
#[builder(default = AUDIO_BUFFER_SIZE)]
buffer_size: u32,
}
impl AnalyzerConfig {
pub fn electronic() -> Self {
Self::builder().min_bpm(100.0).max_bpm(160.0).build()
}
pub fn hip_hop() -> Self {
Self::builder().min_bpm(80.0).max_bpm(110.0).build()
}
pub fn classical() -> Self {
Self::builder().min_bpm(40.0).max_bpm(100.0).build()
}
pub fn rock_pop() -> Self {
Self::builder().min_bpm(110.0).max_bpm(140.0).build()
}
pub fn min_bpm(&self) -> f32 {
self.min_bpm
}
pub fn max_bpm(&self) -> f32 {
self.max_bpm
}
pub fn window_size(&self) -> usize {
self.window_size
}
pub fn queue_size(&self) -> usize {
self.queue_size
}
pub fn buffer_size(&self) -> u32 {
self.buffer_size
}
pub fn validate(&self) -> Result<()> {
if self.min_bpm <= 0.0 {
return Err(Error::InvalidConfig("min_bpm must be positive".to_string()));
}
if self.max_bpm <= self.min_bpm {
return Err(Error::InvalidConfig(
"max_bpm must be greater than min_bpm".to_string(),
));
}
if self.window_size == 0 || !self.window_size.is_power_of_two() {
return Err(Error::InvalidConfig(
"window_size must be a power of 2".to_string(),
));
}
if self.queue_size == 0 {
return Err(Error::InvalidConfig(
"queue_size must be positive".to_string(),
));
}
if self.buffer_size == 0 {
return Err(Error::InvalidConfig(
"buffer_size must be positive".to_string(),
));
}
Ok(())
}
}