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