Skip to main content

rill_core_dsp/macros/
simple.rs

1//! Макрос для создания простого алгоритма без параметров
2//!
3//! # Пример
4//! ```
5//! use rill_core_dsp::simple_algorithm;
6//! use rill_core::math::Transcendental;
7//!
8//! simple_algorithm! {
9//!     /// Простой усилитель
10//!     #[derive(Debug, Clone, Copy)]
11//!     pub struct Gain<T: Transcendental> {
12//!         params: {
13//!             /// Коэффициент усиления
14//!             gain: T = T::from_f32(1.0),
15//!         },
16//!         state: {
17//!             /// Последнее значение (для статистики)
18//!             last_output: T = T::ZERO,
19//!         },
20//!         process: |this, input| {
21//!             let output = input * this.gain;
22//!             this.last_output = output;
23//!             output
24//!         }
25//!     }
26//! }
27//! ```
28
29/// Макрос для создания простого алгоритма без параметров
30///
31/// # Пример
32/// ```
33/// use rill_core_dsp::simple_algorithm;
34/// use rill_core::math::Transcendental;
35///
36/// simple_algorithm! {
37///     /// Простой усилитель
38///     #[derive(Debug, Clone, Copy)]
39///     pub struct Gain<T: Transcendental> {
40///         params: {
41///             /// Коэффициент усиления
42///             gain: T = T::from_f32(1.0),
43///         },
44///         state: {
45///             /// Последнее значение (для статистики)
46///             last_output: T = T::ZERO,
47///         },
48///         process: |this, input| {
49///             let output = input * this.gain;
50///             this.last_output = output;
51///             output
52///         }
53///     }
54/// }
55/// ```
56#[macro_export]
57macro_rules! simple_algorithm {
58    (
59        $(#[$struct_meta:meta])*
60        $vis:vis struct $name:ident<$($generic:ident: $bound:path),+> {
61            params: {
62                $(
63                    $(#[$param_meta:meta])*
64                    $param_name:ident : $param_type:ty = $param_default:expr
65                ),* $(,)?
66            },
67            state: {
68                $(
69                    $(#[$state_meta:meta])*
70                    $state_name:ident : $state_type:ty = $state_default:expr
71                ),* $(,)?
72            },
73            process: $process:expr
74        }
75    ) => {
76        $(#[$struct_meta])*
77        $vis struct $name<$($generic: $bound),+> {
78            $(
79                $(#[$param_meta])*
80                pub $param_name: $param_type,
81            )*
82
83            $(
84                $(#[$state_meta])*
85                pub $state_name: $state_type,
86            )*
87        }
88
89        impl<$($generic: $bound),+> $name<$($generic),+> {
90            /// Создать новый экземпляр алгоритма
91            pub fn new($($param_name: $param_type),*) -> Self {
92                Self {
93                    $($param_name),*,
94                    $($state_name: $state_default),*,
95                }
96            }
97        }
98
99        impl<$($generic: $bound),+> $crate::algorithm::Algorithm<T> for $name<$($generic),+>
100        where
101            T: rill_core::math::Transcendental,
102        {
103            fn init(&mut self, _sample_rate: f32) {}
104
105            fn reset(&mut self) {
106                $(
107                    self.$state_name = $state_default;
108                )*
109            }
110
111            fn process(
112                &mut self,
113                input: Option<&[T]>,
114                output: &mut [T],
115                _ctx: &$crate::algorithm::ActionContext,
116            ) -> $crate::algorithm::ProcessResult<()> {
117                let input = input.unwrap_or(&[]);
118                let len = input.len().min(output.len());
119                let process_fn: fn(&mut Self, T) -> T = $process;
120                for i in 0..len {
121                    output[i] = process_fn(self, input[i]);
122                }
123                Ok(())
124            }
125
126            fn metadata(&self) -> $crate::algorithm::AlgorithmMetadata {
127                $crate::algorithm::AlgorithmMetadata {
128                    name: stringify!($name),
129                    category: $crate::algorithm::AlgorithmCategory::Utility,
130                    description: stringify!($name),
131                    author: "Rill",
132                    version: env!("CARGO_PKG_VERSION"),
133                }
134            }
135        }
136    };
137}