1pub mod algorithm;
7pub mod bridge;
9pub mod buffer_view;
11mod error;
12pub mod multichannel_algorithm;
14pub mod param;
16pub mod parameter_write;
18pub mod rack;
20pub use algorithm::*;
22pub use buffer_view::*;
23pub use error::*;
24pub use multichannel_algorithm::*;
25pub use param::*;
26pub use parameter_write::*;
27pub use rack::*;
28pub const DEFAULT_BLOCK_SIZE: usize = 64;
33pub type MonoBlock<T, const BUF_SIZE: usize> = [T; BUF_SIZE];
35pub type StereoBlock<T, const BUF_SIZE: usize> = [MonoBlock<T, BUF_SIZE>; 2];
37pub type ControlValue<T> = T;
39pub mod prelude {
44 pub use super::{
46 BufferView,
48 Eurorack,
49 ParamMetadata,
50 ParamRange,
51 ParamType,
52 ParamValue,
53 ParameterError,
54 ParameterId,
56 ParameterResult,
57 ParameterWrite,
58 ProcessError,
59 ProcessResult, DEFAULT_BLOCK_SIZE,
62 };
63 pub use crate::math::Transcendental;
65}
66pub trait IntoParamValue: Sized {
71 fn into_param_value(self) -> ParamValue;
73 fn from_param_value(value: ParamValue) -> Option<Self>;
75}
76impl IntoParamValue for f32 {
77 fn into_param_value(self) -> ParamValue {
78 ParamValue::Float(self)
79 }
80 fn from_param_value(value: ParamValue) -> Option<Self> {
81 value.as_f32()
82 }
83}
84impl IntoParamValue for i32 {
85 fn into_param_value(self) -> ParamValue {
86 ParamValue::Int(self)
87 }
88 fn from_param_value(value: ParamValue) -> Option<Self> {
89 value.as_i32()
90 }
91}
92impl IntoParamValue for bool {
93 fn into_param_value(self) -> ParamValue {
94 ParamValue::Bool(self)
95 }
96 fn from_param_value(value: ParamValue) -> Option<Self> {
97 value.as_bool()
98 }
99}
100impl IntoParamValue for String {
101 fn into_param_value(self) -> ParamValue {
102 ParamValue::String(self)
103 }
104 fn from_param_value(value: ParamValue) -> Option<Self> {
105 match value {
106 ParamValue::String(s) => Some(s),
107 ParamValue::Choice(s) => Some(s),
108 _ => None,
109 }
110 }
111}
112pub trait AsAny: 'static {
117 fn as_any(&self) -> &dyn std::any::Any;
119 fn as_any_mut(&mut self) -> &mut dyn std::any::Any;
121}
122impl<T: 'static> AsAny for T {
123 fn as_any(&self) -> &dyn std::any::Any {
124 self
125 }
126 fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
127 self
128 }
129}
130#[cfg(test)]
134mod tests {
135 use super::prelude::*;
136 #[test]
137 fn test_param_value_conversions() {
138 let f = ParamValue::Float(42.0);
139 assert_eq!(f.as_f32(), Some(42.0));
140 assert_eq!(f.as_i32(), Some(42));
141 assert_eq!(f.as_bool(), Some(true));
142 let i = ParamValue::Int(0);
143 assert_eq!(i.as_f32(), Some(0.0));
144 assert_eq!(i.as_i32(), Some(0));
145 assert_eq!(i.as_bool(), Some(false));
146 let b = ParamValue::Bool(true);
147 assert_eq!(b.as_f32(), Some(1.0));
148 assert_eq!(b.as_i32(), Some(1));
149 assert_eq!(b.as_bool(), Some(true));
150 }
151 #[test]
152 fn test_parameter_id_validation() {
153 assert!(ParameterId::new("gain").is_ok());
154 assert!(ParameterId::new("cutoff_freq").is_ok());
155 assert!(ParameterId::new("delay_time_2").is_ok());
156 assert!(ParameterId::new("").is_err());
157 assert!(ParameterId::new("1gain").is_err());
158 assert!(ParameterId::new("_gain").is_err());
159 assert!(ParameterId::new("gain.value").is_ok());
160 }
161 #[test]
162 fn test_param_range() {
163 let range = ParamRange::new().with_min(0.0).with_max(1.0).with_step(0.1);
164 assert!(range.contains(0.5));
165 assert!(!range.contains(1.5));
166 assert_eq!(range.clamp(1.5), 1.0);
167 assert_eq!(range.clamp(-0.5), 0.0);
168 }
169 #[test]
170 fn test_default_block_size() {
171 assert_eq!(DEFAULT_BLOCK_SIZE, 64);
172 }
173}