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    // Core node traits
55    SignalNode,
56    ConnectionError,
57    ConnectionResult,
58    // Parameter conversion
59    IntoParamValue,
60
61    NodeCategory,
62    // Node identification
63    NodeId,
64    NodeMetadata,
65    NodeParams,
66    NodeState,
67
68    NodeTypeId,
69    ParamMetadata,
70
71    ParamRange,
72    ParamType,
73    ParamValue,
74    ParameterError,
75    // Parameter handling
76    ParameterId,
77    ParameterResult,
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,
115    max_slice, min_slice, sin_slice, 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
140    SignalBuffer,
141
142    // Port buffer
143    Buffer,
144
145    // Error types
146    BufferError,
147    BufferResult,
148
149    // Statistics
150    BufferStats,
151
152    DelayLine,
153    FanInBuffer,
154    FanOutBuffer,
155    // Buffer implementations
156    PipeBuffer,
157    RingBuffer,
158};
159
160// ============================================================================
161// Queue Types (from rill-patchbay integration)
162// ============================================================================
163
164pub use crate::queues::{QueueError, QueueResult, TelemetryBlock};
165
166// ============================================================================
167// Constants
168// ============================================================================
169
170pub use crate::{
171    // Cache line alignment
172    CACHE_LINE_SIZE,
173    // Block sizes
174    DEFAULT_BLOCK_SIZE,
175    // Buffer sizes
176    DEFAULT_BUFFER_SIZE,
177    DEFAULT_SAMPLE_RATE,
178
179    MAX_BLOCK_SIZE,
180    MAX_BUFFER_SIZE,
181    // Sample rates
182    MAX_SAMPLE_RATE,
183    MIN_BLOCK_SIZE,
184
185    MIN_BUFFER_SIZE,
186
187    MIN_SAMPLE_RATE,
188    // Version
189    VERSION,
190};
191
192// ============================================================================
193// Common Type Aliases
194// ============================================================================
195
196/// Default sample type (32-bit float)
197pub type Sample = f32;
198
199/// Mono signal block type
200pub type MonoBlock<T, const N: usize> = [T; N];
201
202/// Stereo signal block type (left, right)
203pub type StereoBlock<T, const N: usize> = [MonoBlock<T, N>; 2];
204
205/// Control signal value type
206pub type ControlValue<T> = T;
207
208/// Default pipe buffer with f32 samples
209pub type DefaultPipeBuffer<const N: usize = DEFAULT_BLOCK_SIZE> = PipeBuffer<Sample, N>;
210
211/// Default delay line with f32 samples
212pub type DefaultDelayLine<const MAX_DELAY: usize> = DelayLine<Sample, MAX_DELAY>;
213
214/// Default ring buffer with f32 samples
215pub type DefaultRingBuffer<const N: usize> = RingBuffer<Sample, N>;
216
217/// Default system clock
218pub type DefaultClock = SystemClock;
219
220// ============================================================================
221// Specialized Preludes for Different Use Cases
222// ============================================================================
223
224/// Prelude for working with f32 samples (common case)
225pub mod f32_prelude {
226    use crate::buffer::{DelayLine, FanInBuffer, FanOutBuffer, PipeBuffer, RingBuffer};
227
228    /// Pipe buffer with f32 samples
229    pub type PipeBufferF32<const N: usize> = PipeBuffer<f32, N>;
230
231    /// Fan-out buffer with f32 samples
232    pub type FanOutBufferF32<const N: usize, const CONSUMERS: usize> =
233        FanOutBuffer<f32, N, CONSUMERS>;
234
235    /// Fan-in buffer with f32 samples
236    pub type FanInBufferF32<const N: usize, const PRODUCERS: usize> =
237        FanInBuffer<f32, N, PRODUCERS>;
238
239    /// Delay line with f32 samples
240    pub type DelayLineF32<const MAX_DELAY: usize> = DelayLine<f32, MAX_DELAY>;
241
242    /// Ring buffer with f32 samples
243    pub type RingBufferF32<const N: usize> = RingBuffer<f32, N>;
244
245    /// System clock for f32 (same as default)
246    pub type SystemClockF32 = crate::time::SystemClock;
247
248    // Re-export traits
249    pub use crate::traits::{Processor as ProcessorF32, Sink as SinkF32, Source as SourceF32};
250
251    pub use crate::math::Transcendental;
252}
253
254/// Prelude for working with f64 samples (high precision)
255pub mod f64_prelude {
256    use crate::buffer::{DelayLine, FanInBuffer, FanOutBuffer, PipeBuffer, RingBuffer};
257
258    /// Pipe buffer with f64 samples
259    pub type PipeBufferF64<const N: usize> = PipeBuffer<f64, N>;
260
261    /// Fan-out buffer with f64 samples
262    pub type FanOutBufferF64<const N: usize, const CONSUMERS: usize> =
263        FanOutBuffer<f64, N, CONSUMERS>;
264
265    /// Fan-in buffer with f64 samples
266    pub type FanInBufferF64<const N: usize, const PRODUCERS: usize> =
267        FanInBuffer<f64, N, PRODUCERS>;
268
269    /// Delay line with f64 samples
270    pub type DelayLineF64<const MAX_DELAY: usize> = DelayLine<f64, MAX_DELAY>;
271
272    /// Ring buffer with f64 samples
273    pub type RingBufferF64<const N: usize> = RingBuffer<f64, N>;
274
275    /// System clock for f64 (same as default)
276    pub type SystemClockF64 = crate::time::SystemClock;
277
278    // Re-export traits
279    pub use crate::traits::{Processor as ProcessorF64, Sink as SinkF64, Source as SourceF64};
280
281    pub use crate::math::Transcendental;
282}
283
284/// Prelude for working with time
285pub mod time_prelude {
286    pub use crate::time::{ClockSource, ClockTick, SystemClock, TimeError, TimeResult};
287}
288
289/// Prelude for working with buffers
290pub mod buffer_prelude {
291    pub use crate::buffer::{
292        utils, AtomicCell, AtomicStats, SignalBuffer, BufferError, BufferResult, BufferStats,
293        DelayLine, 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        SignalNode, 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::audio_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);
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::audio_in(NodeId(0), 0);
471        assert!(port.is_audio());
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 = vec![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 = vec![1.0; 4];
490        let right = vec![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}