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