1use crate::error::{Error, Result};
4
5const QUEUE_SIZE: usize = 4096;
7pub(crate) const DWT_LEVELS: usize = 4;
9const AUDIO_BUFFER_SIZE: u32 = 256;
11const DWT_WINDOW_SIZE: usize = 65536;
13pub(crate) const TARGET_SAMPLING_RATE: f64 = 22050.0;
15
16const MIN_BPM: f32 = 40.0;
18const MAX_BPM: f32 = 240.0;
20
21#[derive(Clone, Debug, Copy, bon::Builder)]
37pub struct AnalyzerConfig {
38 #[builder(default = MIN_BPM)]
40 min_bpm: f32,
41 #[builder(default = MAX_BPM)]
43 max_bpm: f32,
44 #[builder(default = DWT_WINDOW_SIZE)]
46 window_size: usize,
47 #[builder(default = QUEUE_SIZE)]
49 queue_size: usize,
50 #[builder(default = AUDIO_BUFFER_SIZE)]
52 buffer_size: u32,
53}
54
55impl AnalyzerConfig {
56 pub fn electronic() -> Self {
58 Self::builder().min_bpm(100.0).max_bpm(160.0).build()
59 }
60
61 pub fn hip_hop() -> Self {
63 Self::builder().min_bpm(80.0).max_bpm(110.0).build()
64 }
65
66 pub fn classical() -> Self {
68 Self::builder().min_bpm(40.0).max_bpm(100.0).build()
69 }
70
71 pub fn rock_pop() -> Self {
73 Self::builder().min_bpm(110.0).max_bpm(140.0).build()
74 }
75
76 pub fn min_bpm(&self) -> f32 {
78 self.min_bpm
79 }
80
81 pub fn max_bpm(&self) -> f32 {
83 self.max_bpm
84 }
85
86 pub fn window_size(&self) -> usize {
88 self.window_size
89 }
90
91 pub fn queue_size(&self) -> usize {
93 self.queue_size
94 }
95
96 pub fn buffer_size(&self) -> u32 {
98 self.buffer_size
99 }
100
101 pub fn validate(&self) -> Result<()> {
103 if self.min_bpm <= 0.0 {
104 return Err(Error::InvalidConfig("min_bpm must be positive".to_string()));
105 }
106 if self.max_bpm <= self.min_bpm {
107 return Err(Error::InvalidConfig(
108 "max_bpm must be greater than min_bpm".to_string(),
109 ));
110 }
111 if self.window_size == 0 || !self.window_size.is_power_of_two() {
112 return Err(Error::InvalidConfig(
113 "window_size must be a power of 2".to_string(),
114 ));
115 }
116 if self.queue_size == 0 {
117 return Err(Error::InvalidConfig(
118 "queue_size must be positive".to_string(),
119 ));
120 }
121 if self.buffer_size == 0 {
122 return Err(Error::InvalidConfig(
123 "buffer_size must be positive".to_string(),
124 ));
125 }
126 Ok(())
127 }
128}