Skip to main content

rill_core/macros/
processor.rs

1//! # Макрос для создания пассивных процессоров (Processor)
2
3/// Создаёт пассивный процессор сигнала
4#[macro_export]
5macro_rules! processor_node {
6    (
7        $(#[$meta:meta])*
8        $vis:vis $struct_name:ident<$T:ident: $audio_num:path, const $BUF:ident: usize>
9        $(where $($bounds:tt)*)?
10        {
11            params { $($param_name:ident: $param_ty:ty = $param_default:expr),* $(,)? }
12            $(ports { $($ports:tt)* } )?
13            process: $process:expr
14        }
15    ) => {
16        #[derive(Debug)]
17        $vis struct $struct_name<$T: $audio_num, const $BUF: usize>
18        $(where $($bounds)*)?
19        {
20            state: $crate::traits::node::NodeState<T,$BUF>,
21            id: $crate::NodeId,
22            metadata: $crate::NodeMetadata,
23            inputs: Vec<$crate::Port<$T, $BUF>>,
24            outputs: Vec<$crate::Port<$T, $BUF>>,
25            controls: Vec<$crate::Port<$T, $BUF>>,
26            $(
27                pub $param_name: $param_ty,
28            )*
29        }
30
31        impl<$T: $audio_num, const $BUF: usize>
32            $struct_name<$T, $BUF>
33        $(where $($bounds)*)?
34        {
35            pub fn new(sample_rate: f32) -> Self {
36                let metadata = $crate::NodeMetadata::new(
37                    stringify!($struct_name),
38                    $crate::NodeCategory::Processor,
39                );
40
41                let mut node = Self {
42                    state: $crate::traits::node::NodeState::new(sample_rate),
43                    id: $crate::NodeId(0),
44                    metadata,
45                    inputs: Vec::new(),
46                    outputs: Vec::new(),
47                    controls: Vec::new(),
48                    $(
49                        $param_name: $param_default,
50                    )*
51                };
52
53                $(
54                    __init_ports!(ports { $($ports)* }, node, inputs, outputs, controls)
55                )?;
56
57                node
58            }
59
60            pub fn sample_rate(&self) -> f32 {
61                self.state.sample_rate
62            }
63
64            pub fn state(&self) -> &$crate::traits::node::NodeState<T,$BUF> {
65                &self.state
66            }
67
68            pub fn state_mut(&mut self) -> &mut $crate::traits::node::NodeState<T,$BUF> {
69                &mut self.state
70            }
71        }
72
73        impl<$T: $audio_num, const $BUF: usize>
74            $crate::AudioNode<$T, $BUF> for $struct_name<$T, $BUF>
75        $(where $($bounds)*)?
76        {
77            fn node_type_id(&self) -> $crate::NodeTypeId
78            where
79                Self: 'static + Sized
80            {
81                $crate::NodeTypeId::of::<Self>()
82            }
83
84            fn id(&self) -> $crate::NodeId {
85                self.id
86            }
87
88            fn set_id(&mut self, id: $crate::NodeId) {
89                self.id = id;
90            }
91
92            fn metadata(&self) -> $crate::NodeMetadata {
93                self.metadata.clone()
94            }
95
96            fn init(&mut self, sample_rate: f32) {
97                self.state.sample_rate = sample_rate;
98            }
99
100            fn reset(&mut self) {
101                self.state.sample_pos = 0;
102                self.state.blocks_processed = 0;
103            }
104
105            fn get_parameter(&self, id: &$crate::ParameterId) -> Option<$crate::ParamValue> {
106                let name = id.as_str();
107                match name {
108                    $(
109                        stringify!($param_name) => Some($crate::ParamValue::Float(
110                            <_ as $crate::math::Transcendental>::to_f32(self.$param_name)
111                        )),
112                    )*
113                    _ => None,
114                }
115            }
116
117            fn set_parameter(&mut self, id: &$crate::ParameterId, value: $crate::ParamValue) -> $crate::ProcessResult<()> {
118                let name = id.as_str();
119                if let Some(v) = value.as_f32() {
120                    match name {
121                        $(
122                            stringify!($param_name) => {
123                                self.$param_name = $crate::math::Transcendental::from_f32(v);
124                                Ok(())
125                            },
126                        )*
127                        _ => Err($crate::ProcessError::parameter(format!("Unknown parameter: {}", name))),
128                    }
129                } else {
130                    Err($crate::ProcessError::parameter("Expected float value"))
131                }
132            }
133
134            fn input_port(&self, index: usize) -> Option<&$crate::Port<$T, $BUF>> {
135                self.inputs.get(index)
136            }
137
138            fn input_port_mut(&mut self, index: usize) -> Option<&mut $crate::Port<$T, $BUF>> {
139                self.inputs.get_mut(index)
140            }
141
142            fn output_port(&self, index: usize) -> Option<&$crate::Port<$T, $BUF>> {
143                self.outputs.get(index)
144            }
145
146            fn output_port_mut(&mut self, index: usize) -> Option<&mut $crate::Port<$T, $BUF>> {
147                self.outputs.get_mut(index)
148            }
149
150            fn control_port(&self, index: usize) -> Option<&$crate::Port<$T, $BUF>> {
151                self.controls.get(index)
152            }
153
154            fn control_port_mut(&mut self, index: usize) -> Option<&mut $crate::Port<$T, $BUF>> {
155                self.controls.get_mut(index)
156            }
157
158            fn num_inputs(&self) -> usize {
159                self.inputs.len()
160            }
161
162            fn num_outputs(&self) -> usize {
163                self.outputs.len()
164            }
165
166            fn state(&self) -> &$crate::traits::node::NodeState<T,$BUF> {
167                &self.state
168            }
169
170            fn state_mut(&mut self) -> &mut $crate::traits::node::NodeState<T,$BUF> {
171                &mut self.state
172            }
173        }
174
175        impl<$T: $crate::math::Transcendental, const $BUF: usize>
176            $crate::Processor<$T, $BUF> for $struct_name<$T, $BUF>
177        $(where $($bounds)*)?
178        {
179            fn process(
180                &mut self,
181                clock: &$crate::ClockTick,
182                audio_inputs: &[&[$T; $BUF]],
183                control_inputs: &[$T],
184                clock_inputs: &[$crate::ClockTick],
185                feedback_inputs: &[&[$T; $BUF]],
186            ) -> $crate::ProcessResult<()> {
187                ($process)(self)?;
188                Ok(())
189            }
190
191            fn latency(&self) -> usize {
192                0
193            }
194        }
195    };
196}