Skip to main content

rill_core/macros/
source.rs

1//! # Macro for creating active sources (Source)
2
3/// Creates an active signal source
4#[macro_export]
5macro_rules! source_node {
6    (
7        $(#[$meta:meta])*
8        $vis:vis $struct_name:ident<$T:ident: $signal_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            generate: $generate:expr
14        }
15    ) => {
16        #[derive(Debug)]
17        $vis struct $struct_name<$T: $signal_num, const $BUF: usize>
18        $(where $($bounds)*)?
19        {
20            /// Internal state
21            state: $crate::traits::node::NodeState<T,$BUF>,
22
23            /// Node identifier
24            id: $crate::NodeId,
25
26            /// Metadata
27            metadata: $crate::NodeMetadata,
28
29            /// Output ports
30            outputs: Vec<$crate::Port<$T, $BUF>>,
31
32            $(
33                pub $param_name: $param_ty,
34            )*
35        }
36
37        impl<$T: $signal_num, const $BUF: usize>
38            $struct_name<$T, $BUF>
39        $(where $($bounds)*)?
40        {
41            /// Create a new source
42            pub fn new(sample_rate: f32) -> Self {
43                let metadata = $crate::NodeMetadata::new(
44                    stringify!($struct_name),
45                    $crate::NodeCategory::Source,
46                );
47
48                let mut node = Self {
49                    state: $crate::traits::node::NodeState::new(sample_rate),
50                    id: $crate::NodeId(0),
51                    metadata,
52                    outputs: Vec::new(),
53                    $(
54                        $param_name: $param_default,
55                    )*
56                };
57
58                $(
59                    __init_ports!(ports { $($ports)* }, node, outputs)
60                )?;
61
62                node
63            }
64
65            /// Get the sample rate
66            pub fn sample_rate(&self) -> f32 {
67                self.state.sample_rate
68            }
69
70            /// Get the node state
71            pub fn state(&self) -> &$crate::traits::node::NodeState<T,$BUF> {
72                &self.state
73            }
74
75            /// Get the mutable state
76            pub fn state_mut(&mut self) -> &mut $crate::traits::node::NodeState<T,$BUF> {
77                &mut self.state
78            }
79        }
80
81        impl<$T: $signal_num, const $BUF: usize>
82            $crate::Node<$T, $BUF> for $struct_name<$T, $BUF>
83        $(where $($bounds)*)?
84        {
85            fn node_type_id(&self) -> $crate::NodeTypeId
86            where
87                Self: 'static + Sized
88            {
89                $crate::NodeTypeId::of::<Self>()
90            }
91
92            fn id(&self) -> $crate::NodeId {
93                self.id
94            }
95
96            fn set_id(&mut self, id: $crate::NodeId) {
97                self.id = id;
98            }
99
100            fn metadata(&self) -> $crate::NodeMetadata {
101                self.metadata.clone()
102            }
103
104            fn init(&mut self, sample_rate: f32) {
105                self.state.sample_rate = sample_rate;
106            }
107
108            fn reset(&mut self) {
109                self.state.sample_pos = 0;
110                self.state.blocks_processed = 0;
111            }
112
113            fn get_parameter(&self, id: &$crate::ParameterId) -> Option<$crate::ParamValue> {
114                let name = id.as_str();
115                match name {
116                    $(
117                        stringify!($param_name) => Some($crate::ParamValue::Float(
118                            <_ as $crate::math::Transcendental>::to_f32(self.$param_name)
119                        )),
120                    )*
121                    _ => None,
122                }
123            }
124
125            fn set_parameter(&mut self, id: &$crate::ParameterId, value: $crate::ParamValue) -> $crate::ProcessResult<()> {
126                let name = id.as_str();
127                if let Some(v) = value.as_f32() {
128                    match name {
129                        $(
130                            stringify!($param_name) => {
131                                self.$param_name = $crate::math::Transcendental::from_f32(v);
132                                Ok(())
133                            },
134                        )*
135                        _ => Err($crate::ProcessError::parameter(format!("Unknown parameter: {}", name))),
136                    }
137                } else {
138                    Err($crate::ProcessError::parameter("Expected float value"))
139                }
140            }
141
142            fn input_port(&self, _index: usize) -> Option<&$crate::Port<$T, $BUF>> {
143                None
144            }
145
146            fn input_port_mut(&mut self, _index: usize) -> Option<&mut $crate::Port<$T, $BUF>> {
147                None
148            }
149
150            fn output_port(&self, index: usize) -> Option<&$crate::Port<$T, $BUF>> {
151                self.outputs.get(index)
152            }
153
154            fn output_port_mut(&mut self, index: usize) -> Option<&mut $crate::Port<$T, $BUF>> {
155                self.outputs.get_mut(index)
156            }
157
158            fn control_port(&self, _index: usize) -> Option<&$crate::Port<$T, $BUF>> {
159                None
160            }
161
162            fn control_port_mut(&mut self, _index: usize) -> Option<&mut $crate::Port<$T, $BUF>> {
163                None
164            }
165
166            fn num_inputs(&self) -> usize { 0 }
167
168            fn num_outputs(&self) -> usize {
169                self.outputs.len()
170            }
171
172            fn state(&self) -> &$crate::traits::node::NodeState<T,$BUF> {
173                &self.state
174            }
175
176            fn state_mut(&mut self) -> &mut $crate::traits::node::NodeState<T,$BUF> {
177                &mut self.state
178            }
179        }
180
181        impl<$T: $crate::math::Transcendental, const $BUF: usize>
182            $crate::Source<$T, $BUF> for $struct_name<$T, $BUF>
183        $(where $($bounds)*)?
184        {
185            fn generate(
186                &mut self,
187                _clock: &$crate::ClockTick,
188                _control_inputs: &[$T],
189                _clock_inputs: &[$crate::ClockTick],
190            ) -> $crate::ProcessResult<()> {
191                ($generate)(self)?;
192                Ok(())
193            }
194
195            fn num_signal_outputs(&self) -> usize { 1 }
196            fn num_control_inputs(&self) -> usize { 0 }
197            fn num_clock_inputs(&self) -> usize { 0 }
198        }
199    };
200}