rill-core 0.6.0-M2

Core foundation for the Rill ecosystem — traits, math, buffers, queues, time, macros
Documentation
//! # Rill Core Prelude
//!
//! This module re-exports the most commonly used types and traits from rill-core.
//! Import it with `use rill_core::prelude::*;` to get access to all essential
//! items for working with the Rill ecosystem.
//!
//! ## What's included
//!
//! - Parameter handling (`ParameterId`, `ParamValue`, `ParamType`)
//! - Time and clock (`ClockTick`, `ClockSource`, `SystemClock`)
//! - Error types (`ProcessResult`, `ProcessError`, etc.)
//! - Buffer types (`PipeBuffer`, `FanOutBuffer`, `DelayLine`, `RingBuffer`)
//! - Atomic types (`AtomicCell`, `AtomicStats`)
//! - Math abstractions (`Transcendental`)
//! - Constants (`DEFAULT_BLOCK_SIZE`, `MAX_SAMPLE_RATE`, etc.)
//!
//! ## Example
//!
//! ```rust
//! use rill_core::prelude::*;
//!
//! let param = ParameterId::new("gain").unwrap();
//! let ctx = RenderContext::new(0, 64, 44100.0);
//! let tick = ClockTick::new(0, 64, 44100.0, "main".to_string());
//! ```

// ============================================================================
// Core Traits
// ============================================================================

pub use crate::traits::{
    Algorithm, AlgorithmCategory, AlgorithmMetadata, IntoParamValue, ParamMetadata, ParamRange,
    ParamType, ParamValue, ParameterError, ParameterId, ParameterResult, Params, ProcessError,
    ProcessResult,
};

// ============================================================================
// Time and Clock
// ============================================================================

pub use crate::time::{ClockSource, ClockTick, RenderContext, SystemClock, TimeError, TimeResult};

// ============================================================================
// Math Abstractions
// ============================================================================

pub use crate::interpolate::Interpolate;

pub use crate::math::Transcendental;

// ============================================================================
// Vector Types (SIMD abstractions)
// ============================================================================

pub use crate::math::vector::complex::{ComplexSoa, ComplexVector};
pub use crate::math::vector::math::{
    abs_slice, clamp_slice, cos_slice, exp_slice, ln_slice, max_slice, min_slice, sin_slice,
    sqrt_slice, tan_slice,
};
pub use crate::math::vector::ops::{
    add_scalar_slice, add_slices, div_slices, mul_scalar_slice, mul_slices, sub_slices, SliceMut,
    SlicePair,
};
pub use crate::math::vector::scalar::{ScalarVector1, ScalarVector2, ScalarVector4, ScalarVector8};
#[cfg(feature = "simd")]
pub use crate::math::vector::simd::*;
pub use crate::math::vector::traits::{
    Vector, VectorMask, VectorReduce, VectorScalarOps, VectorTranscendental,
};

// ============================================================================
// Matrix & Vector (glam)
// ============================================================================

pub use glam::{mat2, mat3, mat4, vec2, vec3, vec4, Mat2, Mat3, Mat4, Vec2, Vec3, Vec4};

// ============================================================================
// Buffer Types
// ============================================================================

pub use crate::buffer::{
    // Utility functions
    utils,
    // Atomic types
    AtomicCell,
    AtomicCellError,
    AtomicStats,

    // Core buffer trait (unified Buffer replaces old Buffer + SignalBuffer)
    Buffer,

    // Error types
    BufferError,
    BufferResult,

    // Statistics
    BufferStats,

    DelayLine,
    FanInBuffer,
    FanOutBuffer,
    // Buffer implementations
    PipeBuffer,
    RingBuffer,
};

// ============================================================================
// Queue Types (from rill-patchbay integration)
// ============================================================================

pub use crate::queues::{QueueError, QueueResult, TelemetryBlock};

// ============================================================================
// Constants
// ============================================================================

pub use crate::{
    // Cache line alignment
    CACHE_LINE_SIZE,
    // Block sizes
    DEFAULT_BLOCK_SIZE,
    // Buffer sizes
    DEFAULT_BUFFER_SIZE,
    DEFAULT_SAMPLE_RATE,

    MAX_BLOCK_SIZE,
    MAX_BUFFER_SIZE,
    // Sample rates
    MAX_SAMPLE_RATE,
    MIN_BLOCK_SIZE,

    MIN_BUFFER_SIZE,

    MIN_SAMPLE_RATE,
    // Version
    VERSION,
};

// ============================================================================
// Common Type Aliases
// ============================================================================

/// Default sample type (32-bit float)
pub type Sample = f32;

/// Mono signal block type
pub type MonoBlock<T, const N: usize> = [T; N];

/// Stereo signal block type (left, right)
pub type StereoBlock<T, const N: usize> = [MonoBlock<T, N>; 2];

/// Control signal value type
pub type ControlValue<T> = T;

/// Default pipe buffer with f32 samples
pub type DefaultPipeBuffer<const N: usize = DEFAULT_BLOCK_SIZE> = PipeBuffer<Sample, N>;

/// Default delay line with f32 samples
pub type DefaultDelayLine<const MAX_DELAY: usize> = DelayLine<Sample, MAX_DELAY>;

/// Default ring buffer with f32 samples
pub type DefaultRingBuffer<const N: usize> = RingBuffer<Sample, N>;

/// Default system clock
pub type DefaultClock = SystemClock;

// ============================================================================
// Specialized Preludes for Different Use Cases
// ============================================================================

/// Prelude for working with f32 samples (common case)
pub mod f32_prelude {
    use crate::buffer::{DelayLine, FanInBuffer, FanOutBuffer, PipeBuffer, RingBuffer};

    /// Pipe buffer with f32 samples
    pub type PipeBufferF32<const N: usize> = PipeBuffer<f32, N>;

    /// Fan-out buffer with f32 samples
    pub type FanOutBufferF32<const N: usize, const CONSUMERS: usize> =
        FanOutBuffer<f32, N, CONSUMERS>;

    /// Fan-in buffer with f32 samples
    pub type FanInBufferF32<const N: usize, const PRODUCERS: usize> =
        FanInBuffer<f32, N, PRODUCERS>;

    /// Delay line with f32 samples
    pub type DelayLineF32<const MAX_DELAY: usize> = DelayLine<f32, MAX_DELAY>;

    /// Ring buffer with f32 samples
    pub type RingBufferF32<const N: usize> = RingBuffer<f32, N>;

    /// System clock for f32 (same as default)
    pub type SystemClockF32 = crate::time::SystemClock;

    pub use crate::math::Transcendental;
}

/// Prelude for working with f64 samples (high precision)
pub mod f64_prelude {
    use crate::buffer::{DelayLine, FanInBuffer, FanOutBuffer, PipeBuffer, RingBuffer};

    /// Pipe buffer with f64 samples
    pub type PipeBufferF64<const N: usize> = PipeBuffer<f64, N>;

    /// Fan-out buffer with f64 samples
    pub type FanOutBufferF64<const N: usize, const CONSUMERS: usize> =
        FanOutBuffer<f64, N, CONSUMERS>;

    /// Fan-in buffer with f64 samples
    pub type FanInBufferF64<const N: usize, const PRODUCERS: usize> =
        FanInBuffer<f64, N, PRODUCERS>;

    /// Delay line with f64 samples
    pub type DelayLineF64<const MAX_DELAY: usize> = DelayLine<f64, MAX_DELAY>;

    /// Ring buffer with f64 samples
    pub type RingBufferF64<const N: usize> = RingBuffer<f64, N>;

    /// System clock for f64 (same as default)
    pub type SystemClockF64 = crate::time::SystemClock;

    pub use crate::math::Transcendental;
}

/// Prelude for working with time
pub mod time_prelude {
    pub use crate::time::{
        ClockSource, ClockTick, RenderContext, SystemClock, TimeError, TimeResult,
    };
}

/// Prelude for working with buffers
pub mod buffer_prelude {
    pub use crate::buffer::{
        utils, AtomicCell, AtomicStats, Buffer, BufferError, BufferResult, BufferStats, DelayLine,
        FanInBuffer, FanOutBuffer, PipeBuffer, RingBuffer,
    };
}

/// Prelude for working with queues (automation)
pub mod queue_prelude {
    pub use crate::queues::{QueueError, QueueResult};
}

/// Prelude for working with parameters
pub mod param_prelude {
    pub use crate::traits::{
        IntoParamValue, ParamMetadata, ParamRange, ParamType, ParamValue, ParameterError,
        ParameterId, ParameterResult,
    };
}

// ============================================================================
// Re-export of commonly used items from other crates
// ============================================================================

/// Common third-party types that are frequently used with Rill
pub mod external {
    pub use std::f32::consts::PI;
    pub use std::f64::consts::PI as PI_F64;
}

// ============================================================================
// Tests
// ============================================================================

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_prelude_imports() {
        let _param_id = ParameterId::new("test").unwrap();
        let _clock = SystemClock::with_sample_rate(44100.0);
        let _tick = ClockTick::new(0, 64, 44100.0, "test".to_string());

        // Test buffer creation
        let _pipe = PipeBuffer::<f32, 64>::new();
        let _delay = DelayLine::<f32, 1024>::new(44100.0);
        let _ring = RingBuffer::<f32, 256>::new();

        // Test atomic cell
        let _cell = AtomicCell::new(42);
    }

    #[test]
    fn test_type_aliases() {
        let _pipe = DefaultPipeBuffer::<64>::new();
        let _delay = DefaultDelayLine::<1024>::new(44100.0);
        let _ring = DefaultRingBuffer::<256>::new();
        let _clock = DefaultClock::with_sample_rate(44100.0);
    }

    #[test]
    fn test_f32_prelude() {
        use f32_prelude::*;

        let _pipe = PipeBufferF32::<64>::new();
        let _fan_out = FanOutBufferF32::<64, 4>::new();
        let _fan_in = FanInBufferF32::<64, 2>::new();
        let _delay = DelayLineF32::<1024>::new(44100.0);
        let _ring = RingBufferF32::<256>::new();
        let _clock = SystemClockF32::with_sample_rate(44100.0);
    }

    #[test]
    fn test_f64_prelude() {
        use f64_prelude::*;

        let _pipe = PipeBufferF64::<64>::new();
        let _fan_out = FanOutBufferF64::<64, 4>::new();
        let _fan_in = FanInBufferF64::<64, 2>::new();
        let _delay = DelayLineF64::<1024>::new(44100.0);
        let _ring = RingBufferF64::<256>::new();
        let _clock = SystemClockF64::with_sample_rate(44100.0);
    }

    #[test]
    fn test_time_prelude() {
        use time_prelude::*;

        let mut clock = SystemClock::with_sample_rate(44100.0);
        let tick = clock.next_tick(64);
        let _pos = tick.absolute_seconds();
    }

    #[test]
    fn test_buffer_prelude() {
        use buffer_prelude::*;

        let buffer = PipeBuffer::<f32, 64>::new();
        let stats = buffer.stats();
        let _fill = stats.fill_level;
    }

    #[test]
    fn test_param_prelude() {
        use param_prelude::*;

        let _id = ParameterId::new("gain").unwrap();
        let value = ParamValue::Float(0.5);
        let _type = value.param_type();
    }

    #[test]
    fn test_constants() {
        assert_eq!(DEFAULT_BLOCK_SIZE, 64);
        assert_eq!(MAX_SAMPLE_RATE, 384_000.0);
        assert_eq!(MIN_SAMPLE_RATE, 8_000.0);
        assert_eq!(CACHE_LINE_SIZE, 64);
    }

    #[test]
    fn test_into_param_value() {
        let f: f32 = 42.0;
        let pv = f.into_param_value();
        assert_eq!(pv.as_f32(), Some(42.0));

        let i: i32 = 42;
        let pv = i.into_param_value();
        assert_eq!(pv.as_i32(), Some(42));

        let b = true;
        let pv = b.into_param_value();
        assert_eq!(pv.as_bool(), Some(true));
    }
}