#![warn(missing_docs)]
#![allow(clippy::doc_lazy_continuation)]
#![deny(unsafe_code)]
#![cfg_attr(not(test), deny(unused))]
#![cfg_attr(docsrs, feature(doc_cfg))]
pub mod traits;
pub mod math;
pub mod buffer;
pub mod queues;
pub mod time;
#[doc(hidden)]
pub use math::vector;
#[macro_use]
pub mod macros;
pub mod prelude;
pub mod interpolate;
pub mod io;
pub mod builtin;
mod error;
pub use error::*;
pub use traits::{
Algorithm, AsAny, IntoParamValue, MultichannelAlgorithm, ParamMetadata, ParamRange, ParamType,
ParamValue, ParameterError, ParameterId, Params, ProcessError, ProcessResult, SisoAdapter,
};
pub use builtin::MultichannelBlockBuiltin;
pub use math::{Scalar, Transcendental};
pub use glam;
pub use buffer::{
AtomicCell, AtomicCellError, AtomicStats, Buffer, BufferError, BufferResult, BufferStats,
DelayLine, FanInBuffer, FanOutBuffer, PipeBuffer, RingBuffer,
};
pub use queues::{QueueError, QueueResult};
pub use time::{ClockSource, ClockTick, RenderContext, SystemClock};
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
pub const MAX_SAMPLE_RATE: f32 = 384_000.0;
pub const MIN_SAMPLE_RATE: f32 = 8_000.0;
pub const DEFAULT_SAMPLE_RATE: f32 = 44_100.0;
pub const DEFAULT_BLOCK_SIZE: usize = 64;
pub const MAX_BLOCK_SIZE: usize = 8192;
pub const MIN_BLOCK_SIZE: usize = 16;
pub const DEFAULT_BUFFER_SIZE: usize = 1024;
pub const MAX_BUFFER_SIZE: usize = 65536;
pub const MIN_BUFFER_SIZE: usize = 16;
pub const CACHE_LINE_SIZE: usize = 64;
pub mod utils {
use crate::math::Transcendental;
#[inline(always)]
pub fn seconds_to_samples(seconds: f32, sample_rate: f32) -> usize {
(seconds * sample_rate) as usize
}
#[inline(always)]
pub fn samples_to_seconds(samples: usize, sample_rate: f32) -> f32 {
samples as f32 / sample_rate
}
#[inline(always)]
pub fn db_to_linear<T: Transcendental>(db: T) -> T {
T::from_f32(10.0_f32.powf(db.to_f32() / 20.0))
}
#[inline(always)]
pub fn linear_to_db<T: Transcendental>(linear: T) -> T {
T::from_f32(20.0 * linear.to_f32().log10())
}
#[inline(always)]
pub const fn is_power_of_two(x: usize) -> bool {
x != 0 && (x & (x - 1)) == 0
}
#[inline(always)]
pub const fn next_power_of_two(x: usize) -> usize {
let mut n = x - 1;
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
n + 1
}
}
pub fn version_info() -> VersionInfo {
VersionInfo {
version: VERSION,
crate_name: env!("CARGO_PKG_NAME"),
authors: env!("CARGO_PKG_AUTHORS"),
description: env!("CARGO_PKG_DESCRIPTION"),
repository: env!("CARGO_PKG_REPOSITORY"),
}
}
#[derive(Debug, Clone)]
pub struct VersionInfo {
pub version: &'static str,
pub crate_name: &'static str,
pub authors: &'static str,
pub description: &'static str,
pub repository: &'static str,
}
#[cfg(test)]
mod tests {
use super::prelude::*;
use super::utils;
#[test]
fn test_constants() {
assert!(!VERSION.is_empty());
const {
assert!(MAX_SAMPLE_RATE > MIN_SAMPLE_RATE);
assert!(MAX_BLOCK_SIZE > MIN_BLOCK_SIZE);
}
assert_eq!(DEFAULT_BLOCK_SIZE, 64);
assert_eq!(DEFAULT_SAMPLE_RATE, 44100.0);
assert_eq!(CACHE_LINE_SIZE, 64);
}
#[test]
fn test_utils() {
assert_eq!(utils::seconds_to_samples(1.0, 44100.0), 44100);
assert!((utils::samples_to_seconds(44100, 44100.0) - 1.0).abs() < 1e-6);
let linear = utils::db_to_linear(0.0f32);
assert!((linear - 1.0).abs() < 1e-6);
let db = utils::linear_to_db(1.0f32);
assert!((db - 0.0).abs() < 1e-6);
assert!(utils::is_power_of_two(64));
assert!(!utils::is_power_of_two(63));
assert_eq!(utils::next_power_of_two(63), 64);
}
#[test]
fn test_atomic_cell() {
let cell = AtomicCell::new(42);
assert_eq!(cell.load(), 42);
cell.store(100);
assert_eq!(cell.load(), 100);
}
}
#[cfg(doctest)]
mod doctests {
}