use core::time::Duration;
use std::sync::Arc;
use crate::{
buffer::SamplesBuffer,
common::{assert_error_traits, ChannelCount, SampleRate},
math, BitDepth, Float, Sample,
};
use dasp_sample::FromSample;
pub use self::agc::{AutomaticGainControl, AutomaticGainControlSettings};
pub use self::amplify::Amplify;
pub use self::blt::BltFilter;
pub use self::buffered::Buffered;
pub use self::channel_volume::ChannelVolume;
pub use self::chirp::{chirp, Chirp};
pub use self::crossfade::Crossfade;
pub use self::delay::Delay;
pub use self::distortion::Distortion;
pub use self::done::Done;
pub use self::empty::Empty;
pub use self::empty_callback::EmptyCallback;
pub use self::fadein::FadeIn;
pub use self::fadeout::FadeOut;
pub use self::from_factory::{from_factory, FromFactoryIter};
pub use self::from_iter::{from_iter, FromIter};
pub use self::limit::{Limit, LimitSettings};
pub use self::linear_ramp::LinearGainRamp;
pub use self::mix::Mix;
pub use self::pausable::Pausable;
pub use self::periodic::PeriodicAccess;
pub use self::position::TrackPosition;
pub use self::repeat::Repeat;
pub use self::sawtooth::SawtoothWave;
pub use self::signal_generator::{Function, GeneratorFunction, SignalGenerator};
pub use self::sine::SineWave;
pub use self::skip::SkipDuration;
pub use self::skippable::Skippable;
pub use self::spatial::Spatial;
pub use self::speed::Speed;
pub use self::square::SquareWave;
pub use self::stoppable::Stoppable;
pub use self::take::TakeDuration;
pub use self::triangle::TriangleWave;
pub use self::uniform::UniformSourceIterator;
pub use self::zero::Zero;
mod agc;
mod amplify;
mod blt;
mod buffered;
mod channel_volume;
mod chirp;
mod crossfade;
mod delay;
mod distortion;
mod done;
mod empty;
mod empty_callback;
mod fadein;
mod fadeout;
mod from_factory;
mod from_iter;
mod limit;
mod linear_ramp;
mod mix;
mod pausable;
mod periodic;
mod position;
mod repeat;
mod sawtooth;
mod signal_generator;
mod sine;
mod skip;
mod skippable;
mod spatial;
mod speed;
mod square;
mod stoppable;
mod take;
mod triangle;
mod uniform;
mod zero;
#[cfg(feature = "dither")]
pub mod dither;
#[cfg(feature = "dither")]
pub use self::dither::{Algorithm as DitherAlgorithm, Dither};
#[cfg(feature = "noise")]
pub mod noise;
#[cfg(feature = "noise")]
pub use self::noise::{Pink, WhiteUniform};
pub trait Source: Iterator<Item = Sample> {
fn current_span_len(&self) -> Option<usize>;
#[inline]
fn is_exhausted(&self) -> bool {
self.current_span_len() == Some(0)
}
fn channels(&self) -> ChannelCount;
fn sample_rate(&self) -> SampleRate;
fn total_duration(&self) -> Option<Duration>;
#[inline]
fn buffered(self) -> Buffered<Self>
where
Self: Sized,
{
buffered::buffered(self)
}
#[cfg(feature = "dither")]
#[inline]
fn dither(self, target_bits: BitDepth, algorithm: DitherAlgorithm) -> Dither<Self>
where
Self: Sized,
{
Dither::new(self, target_bits, algorithm)
}
#[inline]
fn mix<S>(self, other: S) -> Mix<Self, S>
where
Self: Sized,
S: Source,
{
mix::mix(self, other)
}
#[inline]
fn repeat_infinite(self) -> Repeat<Self>
where
Self: Sized,
{
repeat::repeat(self)
}
#[inline]
fn take_duration(self, duration: Duration) -> TakeDuration<Self>
where
Self: Sized,
{
take::take_duration(self, duration)
}
#[inline]
fn delay(self, duration: Duration) -> Delay<Self>
where
Self: Sized,
{
delay::delay(self, duration)
}
#[inline]
fn skip_duration(self, duration: Duration) -> SkipDuration<Self>
where
Self: Sized,
{
skip::skip_duration(self, duration)
}
#[inline]
fn amplify(self, value: Float) -> Amplify<Self>
where
Self: Sized,
{
amplify::amplify(self, value)
}
#[inline]
fn amplify_decibel(self, value: Float) -> Amplify<Self>
where
Self: Sized,
{
amplify::amplify(self, math::db_to_linear(value))
}
#[inline]
fn amplify_normalized(self, value: Float) -> Amplify<Self>
where
Self: Sized,
{
const NORMALIZATION_MIN: Float = 0.0;
const NORMALIZATION_MAX: Float = 1.0;
const LOG_VOLUME_GROWTH_RATE: Float = 6.907_755_4;
const LOG_VOLUME_SCALE_FACTOR: Float = 1000.0;
let value = value.clamp(NORMALIZATION_MIN, NORMALIZATION_MAX);
let mut amplitude = Float::exp(LOG_VOLUME_GROWTH_RATE * value) / LOG_VOLUME_SCALE_FACTOR;
if value < 0.1 {
amplitude *= value * 10.0;
}
amplify::amplify(self, amplitude)
}
#[inline]
fn automatic_gain_control(
self,
agc_settings: AutomaticGainControlSettings,
) -> AutomaticGainControl<Self>
where
Self: Sized,
{
let attack_time_limited = agc_settings.attack_time.min(Duration::from_secs(10));
let release_time_limited = agc_settings.release_time.min(Duration::from_secs(10));
agc::automatic_gain_control(
self,
agc_settings.target_level,
attack_time_limited,
release_time_limited,
agc_settings.absolute_max_gain,
)
}
#[inline]
fn take_crossfade_with<S: Source>(self, other: S, duration: Duration) -> Crossfade<Self, S>
where
Self: Sized,
Self::Item: FromSample<S::Item>,
{
crossfade::crossfade(self, other, duration)
}
#[inline]
fn fade_in(self, duration: Duration) -> FadeIn<Self>
where
Self: Sized,
{
fadein::fadein(self, duration)
}
#[inline]
fn fade_out(self, duration: Duration) -> FadeOut<Self>
where
Self: Sized,
{
fadeout::fadeout(self, duration)
}
fn limit(self, settings: LimitSettings) -> Limit<Self>
where
Self: Sized,
{
limit::limit(self, settings)
}
#[inline]
fn linear_gain_ramp(
self,
duration: Duration,
start_value: Float,
end_value: Float,
clamp_end: bool,
) -> LinearGainRamp<Self>
where
Self: Sized,
{
linear_ramp::linear_gain_ramp(self, duration, start_value, end_value, clamp_end)
}
#[inline]
fn periodic_access<F>(self, period: Duration, access: F) -> PeriodicAccess<Self, F>
where
Self: Sized,
F: FnMut(&mut Self),
{
periodic::periodic(self, period, access)
}
#[inline]
fn speed(self, ratio: f32) -> Speed<Self>
where
Self: Sized,
{
speed::speed(self, ratio)
}
fn record(self) -> SamplesBuffer
where
Self: Sized,
{
SamplesBuffer::record_source(self)
}
#[inline]
fn reverb(self, duration: Duration, amplitude: Float) -> Mix<Self, Delay<Amplify<Self>>>
where
Self: Sized + Clone,
{
let echo = self.clone().amplify(amplitude).delay(duration);
self.mix(echo)
}
#[inline]
fn pausable(self, initially_paused: bool) -> Pausable<Self>
where
Self: Sized,
{
pausable::pausable(self, initially_paused)
}
#[inline]
fn stoppable(self) -> Stoppable<Self>
where
Self: Sized,
{
stoppable::stoppable(self)
}
fn skippable(self) -> Skippable<Self>
where
Self: Sized,
{
skippable::skippable(self)
}
fn track_position(self) -> TrackPosition<Self>
where
Self: Sized,
{
position::track_position(self)
}
#[inline]
fn low_pass(self, freq: u32) -> BltFilter<Self>
where
Self: Sized,
Self: Source<Item = Sample>,
{
blt::low_pass(self, freq)
}
#[inline]
fn high_pass(self, freq: u32) -> BltFilter<Self>
where
Self: Sized,
Self: Source<Item = Sample>,
{
blt::high_pass(self, freq)
}
#[inline]
fn low_pass_with_q(self, freq: u32, q: Float) -> BltFilter<Self>
where
Self: Sized,
Self: Source<Item = Sample>,
{
blt::low_pass_with_q(self, freq, q)
}
#[inline]
fn high_pass_with_q(self, freq: u32, q: Float) -> BltFilter<Self>
where
Self: Sized,
Self: Source<Item = Sample>,
{
blt::high_pass_with_q(self, freq, q)
}
#[inline]
fn distortion(self, gain: Float, threshold: Float) -> Distortion<Self>
where
Self: Sized,
{
distortion::distortion(self, gain, threshold)
}
#[allow(unused_variables)]
fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
Err(SeekError::NotSupported {
underlying_source: std::any::type_name::<Self>(),
})
}
}
#[non_exhaustive]
#[derive(Debug, thiserror::Error, Clone)]
pub enum SeekError {
#[error("Seeking is not supported by source: {underlying_source}")]
NotSupported {
underlying_source: &'static str,
},
#[cfg(feature = "symphonia")]
#[error("Symphonia decoder returned an error")]
SymphoniaDecoder(#[source] crate::decoder::symphonia::SeekError),
#[cfg(feature = "hound")]
#[error("Hound decoder returned an error")]
HoundDecoder(#[source] Arc<std::io::Error>),
#[error(transparent)]
Other(Arc<dyn std::error::Error + Send + Sync + 'static>),
}
assert_error_traits!(SeekError);
#[cfg(feature = "symphonia")]
impl From<crate::decoder::symphonia::SeekError> for SeekError {
fn from(source: crate::decoder::symphonia::SeekError) -> Self {
SeekError::SymphoniaDecoder(source)
}
}
impl SeekError {
pub fn source_intact(&self) -> bool {
match self {
SeekError::NotSupported { .. } => true,
#[cfg(feature = "symphonia")]
SeekError::SymphoniaDecoder(_) => false,
#[cfg(feature = "hound")]
SeekError::HoundDecoder(_) => false,
SeekError::Other(_) => false,
}
}
}
macro_rules! source_pointer_impl {
($($sig:tt)+) => {
impl $($sig)+ {
#[inline]
fn current_span_len(&self) -> Option<usize> {
(**self).current_span_len()
}
#[inline]
fn channels(&self) -> ChannelCount {
(**self).channels()
}
#[inline]
fn sample_rate(&self) -> SampleRate {
(**self).sample_rate()
}
#[inline]
fn total_duration(&self) -> Option<Duration> {
(**self).total_duration()
}
#[inline]
fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
(**self).try_seek(pos)
}
}
};
}
source_pointer_impl!(Source for Box<dyn Source>);
source_pointer_impl!(Source for Box<dyn Source + Send>);
source_pointer_impl!(Source for Box<dyn Source + Send + Sync>);
source_pointer_impl!(<'a, Src> Source for &'a mut Src where Src: Source,);