1pub mod audio;
2pub mod clip;
3pub mod cpal_backend;
4pub mod engine;
5pub mod metronome;
6pub mod mixer;
7pub mod project;
8pub mod transport;
9
10use serde::{Deserialize, Serialize};
11
12#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
14pub struct EngineConfig {
15 pub buffer_size: u32,
18 pub sample_rate: u32,
20}
21
22impl Default for EngineConfig {
23 fn default() -> Self {
24 Self {
25 buffer_size: 64,
26 sample_rate: 44100,
27 }
28 }
29}
30
31impl EngineConfig {
32 pub fn buffer_duration_secs(&self) -> f64 {
34 self.buffer_size as f64 / self.sample_rate as f64
35 }
36
37 pub fn buffer_duration_ms(&self) -> f64 {
39 self.buffer_duration_secs() * 1000.0
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn default_config_is_sensible() {
49 let config = EngineConfig::default();
50 assert_eq!(config.buffer_size, 64);
51 assert_eq!(config.sample_rate, 44100);
52 }
53
54 #[test]
55 fn buffer_duration_calculation() {
56 let config = EngineConfig {
57 buffer_size: 64,
58 sample_rate: 44100,
59 };
60 let ms = config.buffer_duration_ms();
61 assert!((ms - 1.451).abs() < 0.01, "Expected ~1.45ms, got {ms}ms");
62 }
63
64 #[test]
65 fn buffer_duration_various_sizes() {
66 for (size, rate, expected_ms) in [
67 (64, 44100, 1.451),
68 (128, 44100, 2.902),
69 (256, 48000, 5.333),
70 (64, 96000, 0.667),
71 ] {
72 let config = EngineConfig {
73 buffer_size: size,
74 sample_rate: rate,
75 };
76 let ms = config.buffer_duration_ms();
77 assert!(
78 (ms - expected_ms).abs() < 0.01,
79 "size={size} rate={rate}: expected {expected_ms}ms, got {ms}ms"
80 );
81 }
82 }
83}