rodio/common.rs
1use std::fmt::{Debug, Display};
2use std::num::NonZero;
3
4/// Sample rate (a frame rate or samples per second per channel).
5pub type SampleRate = NonZero<u32>;
6
7/// Number of channels in a stream. Can never be Zero
8pub type ChannelCount = NonZero<u16>;
9
10/// Number of bits per sample. Can never be zero.
11pub type BitDepth = NonZero<u32>;
12
13// NOTE on numeric precision:
14//
15// While `f32` is transparent for typical playback use cases, it does not guarantee preservation of
16// full 24-bit source fidelity across arbitrary processing chains. Each floating-point operation
17// rounds its result to `f32` precision (~24-bit significand). In DSP pipelines (filters, mixing,
18// modulation), many operations are applied per sample and over time, so rounding noise accumulates
19// and long-running state (e.g. oscillator phase) can drift.
20//
21// For use cases where numerical accuracy must be preserved through extended processing (recording,
22// editing, analysis, long-running generators, or complex DSP graphs), enabling 64-bit processing
23// reduces accumulated rounding error and drift.
24//
25// This mirrors common practice in professional audio software and DSP libraries, which often use
26// 64-bit internal processing even when the final output is 16- or 24-bit.
27
28/// Floating point type used for internal calculations. Can be configured to be
29/// either `f32` (default) or `f64` using the `64bit` feature flag.
30#[cfg(not(feature = "64bit"))]
31pub type Float = f32;
32
33/// Floating point type used for internal calculations. Can be configured to be
34/// either `f32` (default) or `f64` using the `64bit` feature flag.
35#[cfg(feature = "64bit")]
36pub type Float = f64;
37
38/// Represents value of a single sample.
39/// Silence corresponds to the value `0.0`. The expected amplitude range is -1.0...1.0.
40/// Values below and above this range are clipped in conversion to other sample types.
41/// Use conversion traits from [dasp_sample] crate or [crate::conversions::SampleTypeConverter]
42/// to convert between sample types if necessary.
43pub type Sample = Float;
44
45/// Used to test at compile time that a struct/enum implements Send, Sync and
46/// is 'static. These are common requirements for dynamic error management
47/// libs like color-eyre and anyhow
48///
49/// # Examples
50/// ```compile_fail
51/// struct NotSend {
52/// foo: Rc<String>,
53/// }
54///
55/// assert_error_traits!(NotSend)
56/// ```
57///
58/// ```compile_fail
59/// struct NotSync {
60/// foo: std::cell::RefCell<String>,
61/// }
62/// assert_error_traits!(NotSync)
63/// ```
64///
65/// ```compile_fail
66/// struct NotStatic<'a> {
67/// foo: &'a str,
68/// }
69///
70/// assert_error_traits!(NotStatic)
71/// ```
72macro_rules! assert_error_traits {
73 ($to_test:path) => {
74 const _: () = { $crate::common::use_required_traits::<$to_test>() };
75 };
76}
77
78pub(crate) use assert_error_traits;
79#[allow(dead_code)]
80pub(crate) const fn use_required_traits<T: Send + Sync + 'static + Display + Debug + Clone>() {}