insta_fun/config.rs
1use derive_builder::Builder;
2use fundsp::DEFAULT_SR;
3
4use crate::warmup::WarmUp;
5
6pub use crate::chart::Layout;
7
8const DEFAULT_HEIGHT: usize = 500;
9
10#[derive(Debug, Clone, Builder)]
11/// Configuration for snapshotting an audio unit.
12pub struct SnapshotConfig {
13 // Audio configuration
14 /// Sample rate of the audio unit.
15 ///
16 /// Default is 44100.0 [fundsp::DEFAULT_SR]
17 #[builder(default = "fundsp::DEFAULT_SR")]
18 pub sample_rate: f64,
19 /// Number of samples to generate.
20 ///
21 /// Default is 1024
22 #[builder(default = "1024")]
23 pub num_samples: usize,
24 /// Processing mode for snapshotting an audio unit.
25 ///
26 /// Default - `Tick`
27 #[builder(default = "Processing::default()")]
28 pub processing_mode: Processing,
29 /// Warm-up mode for snapshotting an audio unit.
30 ///
31 /// Default - `WarmUp::None`
32 #[builder(default = "WarmUp::None")]
33 pub warm_up: WarmUp,
34 /// How to handle abnormal samples: `NaN`,`±Infinity`
35 ///
36 /// When set to `true` abnormal samples are allowed during processing,
37 /// but skipped in actual output. Plotted with labeled dots.
38 ///
39 /// When set to `false` and encoutered abnormal samples,
40 /// the snapshotting process will panic.
41 #[builder(default = "false")]
42 pub allow_abnormal_samples: bool,
43
44 // Chart configuration
45 /// Chart layout
46 ///
47 /// Whether to plot channels on separate charts or combined charts.
48 ///
49 /// Default - `Layout::Separate`
50 #[builder(default)]
51 pub chart_layout: Layout,
52 /// Whether to include inputs in snapshot
53 ///
54 /// Default - `false`
55 #[builder(default)]
56 pub with_inputs: bool,
57 /// Optional width of the SVG `viewBox`
58 ///
59 /// `None` means proportional to num_samples
60 #[builder(default, setter(strip_option))]
61 pub svg_width: Option<usize>,
62 /// Height of **one** channel in the SVG `viewBox`
63 ///
64 /// Default - 500
65 #[builder(default = "DEFAULT_HEIGHT")]
66 pub svg_height_per_channel: usize,
67
68 // Chart labels
69 /// Show ax- labels
70 ///
71 /// Default - `true`
72 #[builder(default = "true")]
73 pub show_labels: bool,
74 /// X axis labels format
75 ///
76 /// Whether to format X axis labels as time
77 ///
78 /// Default - `false`
79 #[builder(default)]
80 pub format_x_axis_labels_as_time: bool,
81 /// Maximum number of labels along X axis
82 ///
83 /// Default - `Some(5)`
84 #[builder(default = "Some(5)")]
85 pub max_labels_x_axis: Option<usize>,
86 /// Optional chart title
87 ///
88 /// Default - `None`
89 #[builder(default, setter(into, strip_option))]
90 pub chart_title: Option<String>,
91 /// Optional titles for output channels
92 ///
93 /// Default - empty `Vec`
94 #[builder(default, setter(into, each(into, name = "output_title")))]
95 pub output_titles: Vec<String>,
96 /// Optional titles for input channels
97 ///
98 /// Default - empty `Vec`
99 #[builder(default, setter(into, each(into, name = "input_title")))]
100 pub input_titles: Vec<String>,
101
102 // Lines
103 /// Show grid lines on the chart
104 ///
105 /// Default - `false`
106 #[builder(default)]
107 pub show_grid: bool,
108 /// Waveform line thickness
109 ///
110 /// Default - 2.0
111 #[builder(default = "2.0")]
112 pub line_width: f32,
113
114 // Chart colors
115 /// Chart background color (hex string)
116 ///
117 /// Default - "#000000" (black)
118 #[builder(default = "\"#000000\".to_string()", setter(into))]
119 pub background_color: String,
120 /// Custom colors for output channels (hex strings)
121 ///
122 /// Default - `None` (uses default palette)
123 #[builder(default, setter(into, strip_option, each(into, name = "output_color")))]
124 pub output_colors: Option<Vec<String>>,
125 /// Custom colors for input channels (hex strings)
126 ///
127 /// Default - `None` (uses default palette)
128 #[builder(default, setter(into, strip_option, each(into, name = "input_color")))]
129 pub input_colors: Option<Vec<String>>,
130}
131
132/// Processing mode for snapshotting an audio unit.
133#[derive(Debug, Clone, Copy, Default)]
134pub enum Processing {
135 #[default]
136 /// Process one sample at a time.
137 Tick,
138 /// Process a batch of samples at a time.
139 ///
140 /// max batch size is 64 [fundsp::MAX_BUFFER_SIZE]
141 Batch(u8),
142}
143
144impl Default for SnapshotConfig {
145 fn default() -> Self {
146 Self {
147 num_samples: 1024,
148 sample_rate: DEFAULT_SR,
149 svg_width: None,
150 svg_height_per_channel: DEFAULT_HEIGHT,
151 processing_mode: Processing::default(),
152 with_inputs: false,
153 chart_title: None,
154 output_titles: Vec::new(),
155 input_titles: Vec::new(),
156 show_grid: false,
157 show_labels: true,
158 max_labels_x_axis: Some(5),
159 output_colors: None,
160 input_colors: None,
161 background_color: "#000000".to_string(),
162 line_width: 2.0,
163 warm_up: WarmUp::default(),
164 allow_abnormal_samples: false,
165 chart_layout: Layout::default(),
166 format_x_axis_labels_as_time: false,
167 }
168 }
169}
170
171#[cfg(test)]
172mod tests {
173 use super::*;
174
175 #[test]
176 fn test_default_builder() {
177 SnapshotConfigBuilder::default()
178 .build()
179 .expect("defaul config builds");
180 }
181}