1use super::{
2 envelopes::Adsr,
3 filters::Lpf,
4 operators::{Delay, Mixer, Product},
5 signal::{mk_tag, ArcMutex, Builder, In, Link, Rack, Real, Signal, Tag, Gate},
6};
7use crate::{as_any_mut, std_signal, gate};
8use std::any::Any;
9
10#[derive(Clone)]
11pub struct WaveGuide {
12 tag: Tag,
13 burst: Tag,
14 hz: In,
15 cutoff_freq: In,
16 wet_decay: In,
17 input: ArcMutex<Link>,
18 gate: ArcMutex<Adsr>,
19 lpf: ArcMutex<Lpf>,
20 delay: ArcMutex<Delay>,
21 mixer: ArcMutex<Mixer>,
22 rack: Rack,
23}
24
25impl WaveGuide {
26 pub fn new(burst: Tag) -> Self {
27 let mut rack = Rack::new(vec![]);
28
29 let input = Link::new().wrap();
30 rack.append(input.clone());
31
32 let gate = Adsr::new(0.2, 0.2, 0.2)
34 .attack(0.001)
35 .decay(0)
36 .sustain(0)
37 .release(0.001)
38 .wrap();
39 rack.append(gate.clone());
40
41 let exciter = Product::new(vec![input.tag(), gate.tag()]).wrap();
43 rack.append(exciter.clone());
44
45 let mut mixer = Mixer::new(vec![]).build();
47 let delay = Delay::new(mixer.tag(), (0.02).into()).wrap();
48
49 let cutoff_freq = 2000;
50 let lpf = Lpf::new(delay.tag()).cutoff_freq(cutoff_freq).wrap();
51
52 let wet_decay = 0.95;
53 let mixer = mixer
54 .waves(vec![exciter.tag(), lpf.tag()])
55 .levels(vec![1.0, wet_decay])
56 .wrap();
57
58 rack.append(lpf.clone());
59 rack.append(delay.clone());
60 rack.append(mixer.clone());
61
62 WaveGuide {
63 tag: mk_tag(),
64 burst,
65 hz: 440.into(),
66 cutoff_freq: cutoff_freq.into(),
67 wet_decay: wet_decay.into(),
68 input,
69 gate,
70 lpf,
71 delay,
72 mixer,
73 rack,
74 }
75 }
76
77 pub fn hz<T: Into<In>>(&mut self, arg: T) -> &mut Self {
78 self.hz = arg.into();
79 self
80 }
81
82 pub fn on(&mut self) {
83 self.gate.lock().unwrap().on();
84 }
85
86 pub fn off(&mut self) {
87 self.gate.lock().unwrap().off();
88 }
89
90 pub fn attack<T: Into<In>>(&mut self, arg: T) -> &mut Self {
91 self.gate.lock().unwrap().attack(arg);
92 self
93 }
94
95 pub fn decay<T: Into<In>>(&mut self, arg: T) -> &mut Self {
96 self.gate.lock().unwrap().decay(arg);
97 self
98 }
99
100 pub fn sustain<T: Into<In>>(&mut self, arg: T) -> &mut Self {
101 self.gate.lock().unwrap().sustain(arg);
102 self
103 }
104
105 pub fn release<T: Into<In>>(&mut self, arg: T) -> &mut Self {
106 self.gate.lock().unwrap().release(arg);
107 self
108 }
109
110 pub fn cutoff_freq<T: Into<In>>(&mut self, arg: T) -> &mut Self {
111 self.lpf.lock().unwrap().cutoff_freq(arg);
112 self
113 }
114
115 pub fn wet_decay<T: Into<In>>(&mut self, arg: T) -> &mut Self {
116 self.mixer.lock().unwrap().level_nth(1, arg.into());
117 self
118 }
119}
120
121impl Builder for WaveGuide {}
122
123gate!(WaveGuide);
124
125impl Signal for WaveGuide {
126 std_signal!();
127 fn signal(&mut self, rack: &Rack, sample_rate: Real) -> Real {
128 let input = rack.output(self.burst);
129 self.input.lock().unwrap().value(input);
130 let dt = 1.0 / f64::max(1.0, In::val(&rack, self.hz));
131 self.delay.lock().unwrap().delay_time(dt);
132 self.rack.signal(sample_rate)
133 }
134}
135