1use crate::compiler::component::{
4 Component, ComponentEdge, ControlParam, ControlParamKind, EdgeKind, GraphRole, ModulationSink,
5 ModulationSinkKind, PinConfig, StampResult,
6};
7use crate::dsl::{BbdType, SpringTankType};
8use crate::elements::{Interpolation, Medium};
9use crate::tree::MnaSystem;
10
11use super::impl_component_dyn;
12
13#[derive(Debug, Clone, PartialEq)]
18pub struct Bbd {
19 pub bbd_type: BbdType,
20}
21
22impl Component for Bbd {
23 impl_component_dyn!();
24
25 fn type_tag(&self) -> &'static str {
26 "BBD delay"
27 }
28
29 fn is_passive(&self) -> bool {
30 false
31 }
32
33 fn pin_config(&self) -> PinConfig {
34 PinConfig {
35 valid_pins: &["in", "input", "out", "output", "clock"],
36 aliases: &[("in", "input"), ("out", "output")],
37 }
38 }
39
40 fn modulation_pins(&self) -> &'static [&'static str] {
41 &["clock"]
42 }
43
44 fn graph_role(&self) -> GraphRole {
45 GraphRole::Virtual
46 }
47
48 fn stamp_mna(
49 &self,
50 _comp_id: &str,
51 _n1: Option<usize>,
52 _n2: Option<usize>,
53 _mna: &mut MnaSystem,
54 _sample_rate: f64,
55 ) -> StampResult {
56 StampResult::Skip
57 }
58
59 fn edges(&self) -> Vec<ComponentEdge> {
60 vec![ComponentEdge {
61 pin_a: "input",
62 pin_b: "output",
63 kind: EdgeKind::Behavioral,
64 port_group: None,
65 }]
66 }
67
68 fn controls(&self) -> Vec<ControlParam> {
69 vec![
70 ControlParam {
71 name: "clock",
72 kind: ControlParamKind::BbdClockRate,
73 },
74 ControlParam {
75 name: "feedback",
76 kind: ControlParamKind::BbdFeedback,
77 },
78 ]
79 }
80
81 fn modulation_sink(&self, pin: &str) -> Option<ModulationSink> {
82 match pin {
83 "clock" => Some(ModulationSink {
84 target_kind: ModulationSinkKind::BbdClock,
85 bias: 0.15,
86 range: 0.10,
87 }),
88 _ => None,
89 }
90 }
91
92 fn footprint_ref(&self) -> (&'static str, &'static str) {
93 match self.bbd_type {
94 BbdType::Mn3207 => ("Analog_Delay:MN3207", "IC"),
95 BbdType::Mn3007 => ("Analog_Delay:MN3007", "IC"),
96 BbdType::Mn3005 => ("Analog_Delay:MN3005", "IC"),
97 }
98 }
99
100 fn symbol_name(&self) -> &'static str {
101 "ic_chip"
102 }
103 fn layout_class(&self) -> &'static str {
104 "bbd"
105 }
106
107 fn signal_adjacencies(&self) -> Vec<(&'static str, &'static str)> {
108 vec![
109 ("in", "out"),
110 ("input", "output"),
111 ("in", "input"),
112 ("out", "output"),
113 ]
114 }
115}
116
117#[derive(Debug, Clone, PartialEq)]
126pub struct Spring {
127 pub tank_type: SpringTankType,
128}
129
130impl Component for Spring {
131 impl_component_dyn!();
132
133 fn type_tag(&self) -> &'static str {
134 "spring reverb"
135 }
136
137 fn is_passive(&self) -> bool {
138 false
139 }
140
141 fn pin_config(&self) -> PinConfig {
142 PinConfig {
143 valid_pins: &[
144 "in", "input", "out", "output", "dwell", "decay", "damping", "mix",
145 ],
146 aliases: &[("in", "input"), ("out", "output")],
147 }
148 }
149
150 fn modulation_pins(&self) -> &'static [&'static str] {
151 &["dwell"]
152 }
153
154 fn graph_role(&self) -> GraphRole {
155 GraphRole::Virtual
156 }
157
158 fn stamp_mna(
159 &self,
160 _comp_id: &str,
161 _n1: Option<usize>,
162 _n2: Option<usize>,
163 _mna: &mut MnaSystem,
164 _sample_rate: f64,
165 ) -> StampResult {
166 StampResult::Skip
167 }
168
169 fn edges(&self) -> Vec<ComponentEdge> {
170 vec![ComponentEdge {
171 pin_a: "input",
172 pin_b: "output",
173 kind: EdgeKind::Behavioral,
174 port_group: None,
175 }]
176 }
177
178 fn controls(&self) -> Vec<ControlParam> {
179 vec![
180 ControlParam {
181 name: "dwell",
182 kind: ControlParamKind::SpringDwell,
183 },
184 ControlParam {
185 name: "decay",
186 kind: ControlParamKind::SpringDecay,
187 },
188 ControlParam {
189 name: "damping",
190 kind: ControlParamKind::SpringDamping,
191 },
192 ControlParam {
193 name: "mix",
194 kind: ControlParamKind::SpringMix,
195 },
196 ]
197 }
198
199 fn modulation_sink(&self, pin: &str) -> Option<ModulationSink> {
200 match pin {
201 "dwell" => Some(ModulationSink {
202 target_kind: ModulationSinkKind::SpringDwell,
203 bias: 0.5,
204 range: 0.5,
205 }),
206 _ => None,
207 }
208 }
209
210 fn footprint_ref(&self) -> (&'static str, &'static str) {
211 match self.tank_type {
212 SpringTankType::Type4 => ("Reverb:Accutronics_Type4", "RV"),
213 SpringTankType::Type8 => ("Reverb:Accutronics_Type8", "RV"),
214 SpringTankType::Type9 => ("Reverb:Accutronics_Type9", "RV"),
215 SpringTankType::Re201Tank => ("Reverb:RE201_Tank", "RV"),
216 }
217 }
218
219 fn symbol_name(&self) -> &'static str {
220 "spring"
221 }
222 fn layout_class(&self) -> &'static str {
223 "spring"
224 }
225
226 fn signal_adjacencies(&self) -> Vec<(&'static str, &'static str)> {
227 vec![
228 ("in", "out"),
229 ("input", "output"),
230 ("in", "input"),
231 ("out", "output"),
232 ]
233 }
234}
235
236#[derive(Debug, Clone, PartialEq)]
241pub struct DelayLineComp {
242 pub min_delay: f64,
243 pub max_delay: f64,
244 pub interpolation: Interpolation,
245 pub medium: Medium,
246}
247
248impl Component for DelayLineComp {
249 impl_component_dyn!();
250
251 fn type_tag(&self) -> &'static str {
252 "delay line"
253 }
254
255 fn is_passive(&self) -> bool {
256 false
257 }
258
259 fn pin_config(&self) -> PinConfig {
260 PinConfig {
261 valid_pins: &[
262 "input",
263 "in",
264 "output",
265 "out",
266 "rate",
267 "speed_mod",
268 "delay_time",
269 "feedback",
270 ],
271 aliases: &[("in", "input"), ("out", "output")],
272 }
273 }
274
275 fn modulation_pins(&self) -> &'static [&'static str] {
276 &["speed_mod", "delay_time"]
277 }
278
279 fn graph_role(&self) -> GraphRole {
280 GraphRole::Virtual
281 }
282
283 fn stamp_mna(
284 &self,
285 _comp_id: &str,
286 _n1: Option<usize>,
287 _n2: Option<usize>,
288 _mna: &mut MnaSystem,
289 _sample_rate: f64,
290 ) -> StampResult {
291 StampResult::Skip
292 }
293
294 fn edges(&self) -> Vec<ComponentEdge> {
295 vec![ComponentEdge {
296 pin_a: "input",
297 pin_b: "output",
298 kind: EdgeKind::Behavioral,
299 port_group: None,
300 }]
301 }
302
303 fn controls(&self) -> Vec<ControlParam> {
304 vec![
305 ControlParam {
306 name: "delay_time",
307 kind: ControlParamKind::DelayTime,
308 },
309 ControlParam {
310 name: "feedback",
311 kind: ControlParamKind::DelayFeedback,
312 },
313 ]
314 }
315
316 fn modulation_sink(&self, pin: &str) -> Option<ModulationSink> {
317 match pin {
318 "speed_mod" => Some(ModulationSink {
319 target_kind: ModulationSinkKind::DelaySpeed,
320 bias: 0.0,
321 range: 0.02,
322 }),
323 "delay_time" => Some(ModulationSink {
324 target_kind: ModulationSinkKind::DelayTime,
325 bias: 0.5,
326 range: 0.5,
327 }),
328 _ => None,
329 }
330 }
331
332 fn footprint_ref(&self) -> (&'static str, &'static str) {
333 ("", "DL")
334 }
335
336 fn symbol_name(&self) -> &'static str {
337 "delay"
338 }
339 fn layout_class(&self) -> &'static str {
340 "delay"
341 }
342
343 fn signal_adjacencies(&self) -> Vec<(&'static str, &'static str)> {
344 vec![
345 ("in", "out"),
346 ("input", "output"),
347 ("in", "input"),
348 ("out", "output"),
349 ]
350 }
351}
352
353#[derive(Debug, Clone, PartialEq)]
358pub struct Tap {
359 pub parent_id: String,
360 pub ratio: f64,
361}
362
363impl Component for Tap {
364 impl_component_dyn!();
365
366 fn type_tag(&self) -> &'static str {
367 "tap"
368 }
369
370 fn is_passive(&self) -> bool {
371 false
372 }
373
374 fn pin_config(&self) -> PinConfig {
375 PinConfig {
376 valid_pins: &["output", "out"],
377 aliases: &[("out", "output")],
378 }
379 }
380
381 fn graph_role(&self) -> GraphRole {
382 GraphRole::Virtual
383 }
384
385 fn stamp_mna(
386 &self,
387 _comp_id: &str,
388 _n1: Option<usize>,
389 _n2: Option<usize>,
390 _mna: &mut MnaSystem,
391 _sample_rate: f64,
392 ) -> StampResult {
393 StampResult::Skip
394 }
395
396 fn footprint_ref(&self) -> (&'static str, &'static str) {
397 ("", "TAP")
398 }
399
400 fn symbol_name(&self) -> &'static str {
401 "tap"
402 }
403 fn layout_class(&self) -> &'static str {
404 "tap"
405 }
406}