Skip to main content

max / audiofiles

3.0 KB · 95 lines History Blame Raw
1 //! Analysis configuration: toggles for which analysis modules to run on a batch.
2
3 /// Configuration for which analyses to run on a batch.
4 #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
5 pub struct AnalysisConfig {
6 /// Compute peak, RMS, and LUFS loudness
7 pub loudness: bool,
8 /// Detect BPM via stratum-dsp
9 pub bpm: bool,
10 /// Detect musical key via stratum-dsp
11 pub key: bool,
12 /// Compute spectral features (centroid, flatness, rolloff, ZCR)
13 pub spectral: bool,
14 /// Classify sample type (requires spectral)
15 pub classify: bool,
16 /// Detect if sample is a loop
17 pub loop_detect: bool,
18 /// Generate tag suggestions from results
19 pub auto_suggest_tags: bool,
20 /// Compute peak envelope fingerprint for near-duplicate detection
21 pub fingerprint: bool,
22 /// Maximum seconds of audio to use for expensive analyses (STFT, BPM/key).
23 /// `None` means use the full signal. Default: `Some(30.0)`.
24 /// Fingerprint and peak/RMS always use the full signal.
25 pub max_analysis_seconds: Option<f64>,
26 /// Skip BPM/key/loop for sample types where they don't apply.
27 /// Uses the classification result to decide: drums, impacts, noise, foley,
28 /// ambience, and textures skip BPM/key/loop since those concepts don't apply.
29 /// Requires `classify = true` to have any effect. Default: `true`.
30 pub smart_skip: bool,
31 }
32
33 impl Default for AnalysisConfig {
34 fn default() -> Self {
35 Self {
36 loudness: true,
37 bpm: true,
38 key: true,
39 spectral: true,
40 classify: true,
41 loop_detect: true,
42 auto_suggest_tags: true,
43 fingerprint: true,
44 max_analysis_seconds: Some(30.0),
45 smart_skip: true,
46 }
47 }
48 }
49
50 #[cfg(test)]
51 mod tests {
52 use super::*;
53
54 #[test]
55 fn default_enables_all_features() {
56 let config = AnalysisConfig::default();
57 assert!(config.loudness);
58 assert!(config.bpm);
59 assert!(config.key);
60 assert!(config.spectral);
61 assert!(config.classify);
62 assert!(config.loop_detect);
63 assert!(config.auto_suggest_tags);
64 assert!(config.fingerprint);
65 assert_eq!(config.max_analysis_seconds, Some(30.0));
66 assert!(config.smart_skip);
67 }
68
69 #[test]
70 fn custom_config_with_specific_toggles() {
71 let config = AnalysisConfig {
72 loudness: true,
73 bpm: false,
74 key: false,
75 spectral: true,
76 classify: false,
77 loop_detect: false,
78 auto_suggest_tags: false,
79 fingerprint: false,
80 max_analysis_seconds: None,
81 smart_skip: false,
82 };
83 assert!(config.loudness);
84 assert!(!config.bpm);
85 assert!(!config.key);
86 assert!(config.spectral);
87 assert!(!config.classify);
88 assert!(!config.loop_detect);
89 assert!(!config.auto_suggest_tags);
90 assert!(!config.fingerprint);
91 assert!(config.max_analysis_seconds.is_none());
92 assert!(!config.smart_skip);
93 }
94 }
95