Skip to main content

rill_core/
prelude.rs

1//! # Rill Core Prelude
2//!
3//! This module re-exports the most commonly used types and traits from rill-core.
4//! Import it with `use rill_core::prelude::*;` to get access to all essential
5//! items for working with the Rill ecosystem.
6//!
7//! ## What's included
8//!
9//! - Core traits (`Node`, `Source`, `Processor`, `Sink`)
10//! - Node identification (`NodeId`, `NodeMetadata`, `NodeCategory`)
11//! - Parameter handling (`ParameterId`, `ParamValue`, `ParamType`)
12//! - Ports (`PortId`, `PortType`, `PortDirection`)
13//! - Time and clock (`ClockTick`, `ClockSource`, `SystemClock`)
14//! - Error types (`ProcessResult`, `ProcessError`, etc.)
15//! - Buffer types (`PipeBuffer`, `FanOutBuffer`, `DelayLine`, `RingBuffer`)
16//! - Atomic types (`AtomicCell`, `AtomicStats`)
17//! - Math abstractions (`Scalar`, `Transcendental`)
18//! - Constants (`DEFAULT_BLOCK_SIZE`, `MAX_SAMPLE_RATE`, etc.)
19//!
20//! ## Example
21//!
22// In rill-core/src/lib.rs - line 151 (prelude example)
23
24//! ## Example
25//!
26//! ```rust
27//! use rill_core::prelude::*;
28//!
29//! fn process_block<T: Transcendental, const BUF_SIZE: usize>(
30//!     source: &mut dyn Source<T, BUF_SIZE>,
31//!     processor: &mut dyn Processor<T, BUF_SIZE>,
32//!     sink: &mut dyn Sink<T, BUF_SIZE>,
33//!     clock: &ClockTick,
34//! ) -> ProcessResult<()> {
35//!     source.generate(clock, &[], &[])?;
36//!     processor.process(clock, &[], &[], &[], &[])?;
37//!     sink.consume(clock, &[], &[], &[], &[])?;
38//!     Ok(())
39//! }
40//! ```
41
42// ============================================================================
43// Core Traits
44// ============================================================================
45
46pub use crate::traits::{
47    Action,
48    ActionContext,
49
50    // Algorithm / Action
51    Algorithm,
52    AlgorithmCategory,
53    AlgorithmMetadata,
54    ConnectionError,
55    ConnectionResult,
56    // Parameter conversion
57    IntoParamValue,
58
59    // Core node traits
60    Node,
61    NodeCategory,
62    // Node identification
63    NodeId,
64    NodeMetadata,
65    NodeState,
66
67    NodeTypeId,
68    ParamMetadata,
69
70    ParamRange,
71    ParamType,
72    ParamValue,
73    ParameterError,
74    // Parameter handling
75    ParameterId,
76    ParameterResult,
77    Params,
78    Port,
79
80    PortDirection,
81    PortError,
82    // Ports
83    PortId,
84    PortResult,
85    PortType,
86    ProcessError,
87    // Error handling
88    ProcessResult,
89    Processor,
90    Sink,
91
92    Source,
93};
94
95// ============================================================================
96// Time and Clock
97// ============================================================================
98
99pub use crate::time::{ClockSource, ClockTick, SystemClock, TimeError, TimeResult};
100
101// ============================================================================
102// Math Abstractions
103// ============================================================================
104
105pub use crate::interpolate::Interpolate;
106
107pub use crate::math::Transcendental;
108
109// ============================================================================
110// Vector Types (SIMD abstractions)
111// ============================================================================
112
113pub use crate::math::vector::math::{
114    abs_slice, clamp_slice, cos_slice, exp_slice, ln_slice, max_slice, min_slice, sin_slice,
115    sqrt_slice, tan_slice,
116};
117pub use crate::math::vector::ops::{
118    add_scalar_slice, add_slices, div_slices, mul_scalar_slice, mul_slices, sub_slices,
119};
120pub use crate::math::vector::scalar::{ScalarVector1, ScalarVector2, ScalarVector4, ScalarVector8};
121#[cfg(feature = "simd")]
122pub use crate::math::vector::simd::*;
123pub use crate::math::vector::traits::{
124    Vector, VectorMask, VectorReduce, VectorScalarOps, VectorTranscendental,
125};
126
127// ============================================================================
128// Buffer Types
129// ============================================================================
130
131pub use crate::buffer::{
132    // Utility functions
133    utils,
134    // Atomic types
135    AtomicCell,
136    AtomicCellError,
137    AtomicStats,
138
139    // Core buffer trait (unified Buffer replaces old Buffer + SignalBuffer)
140    Buffer,
141
142    // Error types
143    BufferError,
144    BufferResult,
145
146    // Statistics
147    BufferStats,
148
149    DelayLine,
150    FanInBuffer,
151    FanOutBuffer,
152    // Buffer implementations
153    PipeBuffer,
154    RingBuffer,
155};
156
157// ============================================================================
158// Queue Types (from rill-patchbay integration)
159// ============================================================================
160
161pub use crate::queues::{QueueError, QueueResult, TelemetryBlock};
162
163// ============================================================================
164// Constants
165// ============================================================================
166
167pub use crate::{
168    // Cache line alignment
169    CACHE_LINE_SIZE,
170    // Block sizes
171    DEFAULT_BLOCK_SIZE,
172    // Buffer sizes
173    DEFAULT_BUFFER_SIZE,
174    DEFAULT_SAMPLE_RATE,
175
176    MAX_BLOCK_SIZE,
177    MAX_BUFFER_SIZE,
178    // Sample rates
179    MAX_SAMPLE_RATE,
180    MIN_BLOCK_SIZE,
181
182    MIN_BUFFER_SIZE,
183
184    MIN_SAMPLE_RATE,
185    // Version
186    VERSION,
187};
188
189// ============================================================================
190// Common Type Aliases
191// ============================================================================
192
193/// Default sample type (32-bit float)
194pub type Sample = f32;
195
196/// Mono signal block type
197pub type MonoBlock<T, const N: usize> = [T; N];
198
199/// Stereo signal block type (left, right)
200pub type StereoBlock<T, const N: usize> = [MonoBlock<T, N>; 2];
201
202/// Control signal value type
203pub type ControlValue<T> = T;
204
205/// Default pipe buffer with f32 samples
206pub type DefaultPipeBuffer<const N: usize = DEFAULT_BLOCK_SIZE> = PipeBuffer<Sample, N>;
207
208/// Default delay line with f32 samples
209pub type DefaultDelayLine<const MAX_DELAY: usize> = DelayLine<Sample, MAX_DELAY>;
210
211/// Default ring buffer with f32 samples
212pub type DefaultRingBuffer<const N: usize> = RingBuffer<Sample, N>;
213
214/// Default system clock
215pub type DefaultClock = SystemClock;
216
217// ============================================================================
218// Specialized Preludes for Different Use Cases
219// ============================================================================
220
221/// Prelude for working with f32 samples (common case)
222pub mod f32_prelude {
223    use crate::buffer::{DelayLine, FanInBuffer, FanOutBuffer, PipeBuffer, RingBuffer};
224
225    /// Pipe buffer with f32 samples
226    pub type PipeBufferF32<const N: usize> = PipeBuffer<f32, N>;
227
228    /// Fan-out buffer with f32 samples
229    pub type FanOutBufferF32<const N: usize, const CONSUMERS: usize> =
230        FanOutBuffer<f32, N, CONSUMERS>;
231
232    /// Fan-in buffer with f32 samples
233    pub type FanInBufferF32<const N: usize, const PRODUCERS: usize> =
234        FanInBuffer<f32, N, PRODUCERS>;
235
236    /// Delay line with f32 samples
237    pub type DelayLineF32<const MAX_DELAY: usize> = DelayLine<f32, MAX_DELAY>;
238
239    /// Ring buffer with f32 samples
240    pub type RingBufferF32<const N: usize> = RingBuffer<f32, N>;
241
242    /// System clock for f32 (same as default)
243    pub type SystemClockF32 = crate::time::SystemClock;
244
245    // Re-export traits
246    pub use crate::traits::{Processor as ProcessorF32, Sink as SinkF32, Source as SourceF32};
247
248    pub use crate::math::Transcendental;
249}
250
251/// Prelude for working with f64 samples (high precision)
252pub mod f64_prelude {
253    use crate::buffer::{DelayLine, FanInBuffer, FanOutBuffer, PipeBuffer, RingBuffer};
254
255    /// Pipe buffer with f64 samples
256    pub type PipeBufferF64<const N: usize> = PipeBuffer<f64, N>;
257
258    /// Fan-out buffer with f64 samples
259    pub type FanOutBufferF64<const N: usize, const CONSUMERS: usize> =
260        FanOutBuffer<f64, N, CONSUMERS>;
261
262    /// Fan-in buffer with f64 samples
263    pub type FanInBufferF64<const N: usize, const PRODUCERS: usize> =
264        FanInBuffer<f64, N, PRODUCERS>;
265
266    /// Delay line with f64 samples
267    pub type DelayLineF64<const MAX_DELAY: usize> = DelayLine<f64, MAX_DELAY>;
268
269    /// Ring buffer with f64 samples
270    pub type RingBufferF64<const N: usize> = RingBuffer<f64, N>;
271
272    /// System clock for f64 (same as default)
273    pub type SystemClockF64 = crate::time::SystemClock;
274
275    // Re-export traits
276    pub use crate::traits::{Processor as ProcessorF64, Sink as SinkF64, Source as SourceF64};
277
278    pub use crate::math::Transcendental;
279}
280
281/// Prelude for working with time
282pub mod time_prelude {
283    pub use crate::time::{ClockSource, ClockTick, SystemClock, TimeError, TimeResult};
284}
285
286/// Prelude for working with buffers
287pub mod buffer_prelude {
288    pub use crate::buffer::{
289        utils, AtomicCell, AtomicStats, Buffer, BufferError, BufferResult, BufferStats, DelayLine,
290        FanInBuffer, FanOutBuffer, PipeBuffer, RingBuffer,
291    };
292}
293
294/// Prelude for working with queues (automation)
295pub mod queue_prelude {
296    pub use crate::queues::{QueueError, QueueResult};
297}
298
299/// Prelude for working with parameters
300pub mod param_prelude {
301    pub use crate::traits::{
302        IntoParamValue, ParamMetadata, ParamRange, ParamType, ParamValue, ParameterError,
303        ParameterId, ParameterResult,
304    };
305}
306
307/// Prelude for working with ports
308pub mod port_prelude {
309    pub use crate::traits::{PortDirection, PortError, PortId, PortResult, PortType};
310}
311
312/// Prelude for working with nodes
313pub mod node_prelude {
314    pub use crate::traits::{
315        Node, NodeCategory, NodeId, NodeMetadata, NodeTypeId, Processor, Sink, Source,
316    };
317}
318
319// ============================================================================
320// Re-export of commonly used items from other crates
321// ============================================================================
322
323/// Common third-party types that are frequently used with Rill
324pub mod external {
325    pub use std::f32::consts::PI;
326    pub use std::f64::consts::PI as PI_F64;
327}
328
329// ============================================================================
330// Helper macros for common operations
331// ============================================================================
332
333/// Macro for creating a mono block from a slice
334///
335/// # Example
336/// ```
337/// use rill_core::mono_block;
338///
339/// let data = vec![1.0, 2.0, 3.0];
340/// let block = mono_block!(data, 64);
341/// ```
342#[macro_export]
343macro_rules! mono_block {
344    ($data:expr, $size:expr) => {{
345        let mut block = [0.0; $size];
346        let len = $data.len().min($size);
347        block[..len].copy_from_slice(&$data[..len]);
348        block
349    }};
350}
351
352/// Macro for creating a stereo block from slices
353///
354/// # Example
355/// ```
356/// use rill_core::stereo_block;
357///
358/// let left = vec![1.0; 64];
359/// let right = vec![2.0; 64];
360/// let block = stereo_block!(left, right, 64);
361/// ```
362#[macro_export]
363macro_rules! stereo_block {
364    ($left:expr, $right:expr, $size:expr) => {{
365        let mut left_block = [0.0; $size];
366        let mut right_block = [0.0; $size];
367
368        let left_len = $left.len().min($size);
369        left_block[..left_len].copy_from_slice(&$left[..left_len]);
370
371        let right_len = $right.len().min($size);
372        right_block[..right_len].copy_from_slice(&$right[..right_len]);
373
374        [left_block, right_block]
375    }};
376}
377
378// ============================================================================
379// Tests
380// ============================================================================
381
382#[cfg(test)]
383mod tests {
384    use super::*;
385
386    #[test]
387    fn test_prelude_imports() {
388        // Verify that all expected types are accessible
389        let _node_id = NodeId(0);
390        let _port_id = PortId::signal_in(_node_id, 0);
391        let _param_id = ParameterId::new("test").unwrap();
392        let _clock = SystemClock::with_sample_rate(44100.0);
393        let _tick = ClockTick::new(0, 64, 44100.0);
394
395        // Test buffer creation
396        let _pipe = PipeBuffer::<f32, 64>::new();
397        let _delay = DelayLine::<f32, 1024>::new(44100.0);
398        let _ring = RingBuffer::<f32, 256>::new();
399
400        // Test atomic cell
401        let _cell = AtomicCell::new(42);
402    }
403
404    #[test]
405    fn test_type_aliases() {
406        let _pipe = DefaultPipeBuffer::<64>::new();
407        let _delay = DefaultDelayLine::<1024>::new(44100.0);
408        let _ring = DefaultRingBuffer::<256>::new();
409        let _clock = DefaultClock::with_sample_rate(44100.0);
410    }
411
412    #[test]
413    fn test_f32_prelude() {
414        use f32_prelude::*;
415
416        let _pipe = PipeBufferF32::<64>::new();
417        let _fan_out = FanOutBufferF32::<64, 4>::new();
418        let _fan_in = FanInBufferF32::<64, 2>::new();
419        let _delay = DelayLineF32::<1024>::new(44100.0);
420        let _ring = RingBufferF32::<256>::new();
421        let _clock = SystemClockF32::with_sample_rate(44100.0);
422    }
423
424    #[test]
425    fn test_f64_prelude() {
426        use f64_prelude::*;
427
428        let _pipe = PipeBufferF64::<64>::new();
429        let _fan_out = FanOutBufferF64::<64, 4>::new();
430        let _fan_in = FanInBufferF64::<64, 2>::new();
431        let _delay = DelayLineF64::<1024>::new(44100.0);
432        let _ring = RingBufferF64::<256>::new();
433        let _clock = SystemClockF64::with_sample_rate(44100.0);
434    }
435
436    #[test]
437    fn test_time_prelude() {
438        use time_prelude::*;
439
440        let mut clock = SystemClock::with_sample_rate(44100.0);
441        let tick = clock.next_tick(64);
442        let _pos = tick.absolute_seconds();
443    }
444
445    #[test]
446    fn test_buffer_prelude() {
447        use buffer_prelude::*;
448
449        let buffer = PipeBuffer::<f32, 64>::new();
450        let stats = buffer.stats();
451        let _fill = stats.fill_level;
452    }
453
454    #[test]
455    fn test_param_prelude() {
456        use param_prelude::*;
457
458        let _id = ParameterId::new("gain").unwrap();
459        let value = ParamValue::Float(0.5);
460        let _type = value.param_type();
461    }
462
463    #[test]
464    fn test_port_prelude() {
465        use port_prelude::*;
466
467        let port = PortId::signal_in(NodeId(0), 0);
468        assert!(port.is_signal());
469        assert!(port.is_input());
470    }
471
472    #[test]
473    fn test_constants() {
474        assert_eq!(DEFAULT_BLOCK_SIZE, 64);
475        assert_eq!(MAX_SAMPLE_RATE, 384_000.0);
476        assert_eq!(MIN_SAMPLE_RATE, 8_000.0);
477        assert_eq!(CACHE_LINE_SIZE, 64);
478    }
479
480    #[test]
481    fn test_macros() {
482        let data = vec![1.0, 2.0, 3.0];
483        let block = mono_block!(data, 4);
484        assert_eq!(block, [1.0, 2.0, 3.0, 0.0]);
485
486        let left = vec![1.0; 4];
487        let right = vec![2.0; 4];
488        let stereo = stereo_block!(left, right, 4);
489        assert_eq!(stereo[0], [1.0; 4]);
490        assert_eq!(stereo[1], [2.0; 4]);
491    }
492
493    #[test]
494    fn test_into_param_value() {
495        let f: f32 = 42.0;
496        let pv = f.into_param_value();
497        assert_eq!(pv.as_f32(), Some(42.0));
498
499        let i: i32 = 42;
500        let pv = i.into_param_value();
501        assert_eq!(pv.as_i32(), Some(42));
502
503        let b = true;
504        let pv = b.into_param_value();
505        assert_eq!(pv.as_bool(), Some(true));
506    }
507}