// Copyright 2026 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///|
pub struct Amplify {
input : DynSource
factor : Ref[Sample]
}
///|
pub fn[S : Source] Amplify::new(source : S, factor : Sample) -> Amplify {
{ input: to_dyn(source), factor: @ref.new(factor) }
}
///|
pub fn Amplify::set_factor(self : Amplify, factor : Sample) -> Unit {
self.factor.val = factor
}
///|
pub fn Amplify::set_log_factor(self : Amplify, factor : Sample) -> Unit {
self.factor.val = @math.pow(10.0, factor / 20.0)
}
///|
pub fn Amplify::inner(self : Amplify) -> DynSource {
self.input
}
///|
pub fn Amplify::inner_mut(self : Amplify) -> DynSource {
self.input
}
///|
pub fn Amplify::into_inner(self : Amplify) -> DynSource {
self.input
}
///|
pub struct Buffered {
inner : SamplesBuffer
}
///|
pub fn[S : Source] Buffered::new(source : S) -> Buffered {
{ inner: buffered(source) }
}
///|
pub fn Buffered::inner(self : Buffered) -> SamplesBuffer {
self.inner
}
///|
pub fn Buffered::inner_mut(self : Buffered) -> SamplesBuffer {
self.inner
}
///|
pub fn Buffered::into_inner(self : Buffered) -> SamplesBuffer {
self.inner
}
///|
pub struct ChannelVolume {
input : DynSource
channel_factors : Ref[Array[Sample]]
current_channel : Ref[Int]
current_sample : Ref[Sample?]
}
///|
pub fn[S : Source] ChannelVolume::new(
source : S,
channel_factors : Array[Sample],
) -> ChannelVolume {
guard !channel_factors.is_empty() else { panic() }
let out_channels = channel_factors.length()
{
input: to_dyn(source),
channel_factors: @ref.new(channel_factors),
current_channel: @ref.new(out_channels),
current_sample: @ref.new(None),
}
}
///|
pub fn ChannelVolume::set_volume(
self : ChannelVolume,
channel : Int,
volume : Sample,
) -> Unit {
guard channel >= 0 && channel < self.channel_factors.val.length() else {
panic()
}
self.channel_factors.val[channel] = volume
}
///|
pub fn ChannelVolume::inner(self : ChannelVolume) -> DynSource {
self.input
}
///|
pub fn ChannelVolume::inner_mut(self : ChannelVolume) -> DynSource {
self.input
}
///|
pub fn ChannelVolume::into_inner(self : ChannelVolume) -> DynSource {
self.input
}
///|
pub struct Crossfade {
inner : DynSource
}
///|
pub fn[A : Source, B : Source] Crossfade::new(
left : A,
right : B,
duration : @moon_cpal.Duration,
) -> Crossfade {
{ inner: crossfade(left, right, duration) }
}
///|
pub fn Crossfade::inner(self : Crossfade) -> DynSource {
self.inner
}
///|
pub fn Crossfade::inner_mut(self : Crossfade) -> DynSource {
self.inner
}
///|
pub fn Crossfade::into_inner(self : Crossfade) -> DynSource {
self.inner
}
///|
pub struct Delay {
inner : DynSource
}
///|
pub fn[S : Source] Delay::new(
source : S,
duration : @moon_cpal.Duration,
) -> Delay {
{ inner: delay(source, duration) }
}
///|
pub fn Delay::inner(self : Delay) -> DynSource {
self.inner
}
///|
pub fn Delay::inner_mut(self : Delay) -> DynSource {
self.inner
}
///|
pub fn Delay::into_inner(self : Delay) -> DynSource {
self.inner
}
///|
pub struct Distortion {
input : DynSource
gain : Ref[Sample]
threshold : Ref[Sample]
}
///|
pub fn[S : Source] Distortion::new(
source : S,
gain : Sample,
threshold : Sample,
) -> Distortion {
{
input: to_dyn(source),
gain: @ref.new(gain),
threshold: @ref.new(threshold),
}
}
///|
pub fn[S : Source] Distortion::new_with_threshold(
source : S,
threshold : Sample,
) -> Distortion {
Distortion::new(source, 1.0, threshold)
}
///|
pub fn[S : Source] Distortion::with_gain(
source : S,
gain : Sample,
threshold : Sample,
) -> Distortion {
Distortion::new(source, gain, threshold)
}
///|
pub fn Distortion::set_gain(self : Distortion, gain : Sample) -> Unit {
self.gain.val = gain
}
///|
pub fn Distortion::set_threshold(self : Distortion, threshold : Sample) -> Unit {
self.threshold.val = threshold
}
///|
pub fn Distortion::inner(self : Distortion) -> DynSource {
self.input
}
///|
pub fn Distortion::inner_mut(self : Distortion) -> DynSource {
self.input
}
///|
pub fn Distortion::into_inner(self : Distortion) -> DynSource {
self.input
}
///|
pub struct Empty {
inner : DynSource
}
///|
pub fn Empty::new(channels : ChannelCount, sample_rate : SampleRate) -> Empty {
{ inner: empty(channels, sample_rate) }
}
///|
pub fn Empty::inner(self : Empty) -> DynSource {
self.inner
}
///|
pub fn Empty::inner_mut(self : Empty) -> DynSource {
self.inner
}
///|
pub fn Empty::into_inner(self : Empty) -> DynSource {
self.inner
}
///|
pub struct FadeIn {
inner : DynSource
}
///|
pub fn[S : Source] FadeIn::new(
source : S,
duration : @moon_cpal.Duration,
) -> FadeIn {
{ inner: fade_in(source, duration) }
}
///|
pub fn FadeIn::inner(self : FadeIn) -> DynSource {
self.inner
}
///|
pub fn FadeIn::inner_mut(self : FadeIn) -> DynSource {
self.inner
}
///|
pub fn FadeIn::into_inner(self : FadeIn) -> DynSource {
self.inner
}
///|
pub struct FadeOut {
inner : DynSource
}
///|
pub fn[S : Source] FadeOut::new(
source : S,
duration : @moon_cpal.Duration,
) -> FadeOut {
{ inner: fade_out(source, duration) }
}
///|
pub fn FadeOut::inner(self : FadeOut) -> DynSource {
self.inner
}
///|
pub fn FadeOut::inner_mut(self : FadeOut) -> DynSource {
self.inner
}
///|
pub fn FadeOut::into_inner(self : FadeOut) -> DynSource {
self.inner
}
///|
fn duration_from_millis(ms : Int) -> @moon_cpal.Duration {
let secs = ms / 1000
let nanos = ms % 1000 * 1_000_000
@moon_cpal.Duration::new(secs.to_uint64(), nanos)
}
///|
fn duration_from_micros(us : Int) -> @moon_cpal.Duration {
let secs = us / 1_000_000
let nanos = us % 1_000_000 * 1_000
@moon_cpal.Duration::new(secs.to_uint64(), nanos)
}
///|
fn limit_duration_to_secs(duration : @moon_cpal.Duration) -> Double {
Double::from_int(duration.secs.to_int()) +
Double::from_int(duration.nanos) / 1_000_000_000.0
}
///|
fn limit_duration_to_coefficient(
duration : @moon_cpal.Duration,
sample_rate : SampleRate,
) -> Sample {
let secs = limit_duration_to_secs(duration)
if secs <= 0.0 || sample_rate <= 0 {
0.0
} else {
@math.exp(-1.0 / (secs * Double::from_int(sample_rate)))
}
}
///|
fn limit_peak_from_threshold(threshold : Sample) -> Sample {
db_to_linear(threshold)
}
///|
fn limit_threshold_from_peak(peak : Sample) -> Sample {
if peak <= 0.0 {
-120.0
} else {
linear_to_db(peak)
}
}
///|
fn limit_peak_from_range(min_value : Sample, max_value : Sample) -> Sample {
let min_peak = min_value.abs()
let max_peak = max_value.abs()
if min_peak > max_peak {
min_peak
} else {
max_peak
}
}
///|
fn limit_reduction_db(
sample : Sample,
threshold : Sample,
knee_width : Sample,
) -> Sample {
let bias_db = linear_to_db(sample.abs() + 1.0e-12) - threshold
if knee_width <= 0.0 {
if bias_db <= 0.0 {
0.0
} else {
bias_db
}
} else {
let knee_boundary_db = bias_db * 2.0
if knee_boundary_db < -knee_width {
0.0
} else if knee_boundary_db.abs() <= knee_width {
let x = knee_boundary_db + knee_width
x * x / (8.0 * knee_width)
} else {
bias_db
}
}
}
///|
fn limit_max_peak(peaks : Array[Sample]) -> Sample {
let max_peak = @ref.new(0.0)
for peak in peaks {
if peak > max_peak.val {
max_peak.val = peak
}
}
max_peak.val
}
///|
pub struct LimitSettings {
min_value : Sample
max_value : Sample
threshold : Sample
knee_width : Sample
attack : @moon_cpal.Duration
release : @moon_cpal.Duration
} derive(Show, Eq)
///|
pub fn LimitSettings::default() -> LimitSettings {
{
min_value: -1.0,
max_value: 1.0,
threshold: -1.0,
knee_width: 4.0,
attack: duration_from_millis(5),
release: duration_from_millis(100),
}
}
///|
pub fn LimitSettings::new() -> LimitSettings {
LimitSettings::default()
}
///|
pub fn LimitSettings::with_min(
self : LimitSettings,
min_value : Sample,
) -> LimitSettings {
let peak = limit_peak_from_range(min_value, self.max_value)
{ ..self, min_value, threshold: limit_threshold_from_peak(peak) }
}
///|
pub fn LimitSettings::with_max(
self : LimitSettings,
max_value : Sample,
) -> LimitSettings {
let peak = limit_peak_from_range(self.min_value, max_value)
{ ..self, max_value, threshold: limit_threshold_from_peak(peak) }
}
///|
pub fn LimitSettings::with_threshold(
self : LimitSettings,
threshold : Sample,
) -> LimitSettings {
let peak = limit_peak_from_threshold(threshold)
{ ..self, min_value: -peak, max_value: peak, threshold }
}
///|
pub fn LimitSettings::with_knee_width(
self : LimitSettings,
knee_width : Sample,
) -> LimitSettings {
{ ..self, knee_width, }
}
///|
pub fn LimitSettings::with_attack(
self : LimitSettings,
attack : @moon_cpal.Duration,
) -> LimitSettings {
{ ..self, attack, }
}
///|
pub fn LimitSettings::with_release(
self : LimitSettings,
release : @moon_cpal.Duration,
) -> LimitSettings {
{ ..self, release, }
}
///|
pub fn LimitSettings::dynamic_content() -> LimitSettings {
LimitSettings::default().with_threshold(-3.0).with_knee_width(6.0)
}
///|
pub fn LimitSettings::broadcast() -> LimitSettings {
LimitSettings::default()
.with_knee_width(2.0)
.with_attack(duration_from_millis(3))
.with_release(duration_from_millis(50))
}
///|
pub fn LimitSettings::mastering() -> LimitSettings {
LimitSettings::new()
.with_threshold(-0.5)
.with_knee_width(1.0)
.with_attack(duration_from_millis(1))
.with_release(duration_from_millis(200))
}
///|
pub fn LimitSettings::gaming() -> LimitSettings {
LimitSettings::new()
.with_threshold(-3.0)
.with_knee_width(3.0)
.with_attack(duration_from_millis(2))
.with_release(duration_from_millis(75))
}
///|
pub fn LimitSettings::live_performance() -> LimitSettings {
LimitSettings::new()
.with_threshold(-2.0)
.with_knee_width(3.0)
.with_attack(duration_from_micros(500))
.with_release(duration_from_millis(30))
}
///|
pub struct Limit {
input : DynSource
settings : LimitSettings
attack_coeff : Sample
release_coeff : Sample
integrators : Ref[Array[Sample]]
peaks : Ref[Array[Sample]]
position : Ref[Int]
}
///|
pub fn[S : Source] Limit::new(source : S, settings : LimitSettings) -> Limit {
let input = to_dyn(source)
let channels = input.channels()
let integrators : Array[Sample] = []
let peaks : Array[Sample] = []
for _ in 0.. DynSource {
self.input
}
///|
pub fn Limit::inner_mut(self : Limit) -> DynSource {
self.input
}
///|
pub fn Limit::into_inner(self : Limit) -> DynSource {
self.input
}
///|
fn Limit::reset_state(self : Limit) -> Unit {
self.position.val = 0
for i in 0.. LimitMono {
{ inner: Limit::new(source, settings) }
}
///|
pub fn LimitMono::inner(self : LimitMono) -> Limit {
self.inner
}
///|
pub fn LimitMono::inner_mut(self : LimitMono) -> Limit {
self.inner
}
///|
pub fn LimitMono::into_inner(self : LimitMono) -> Limit {
self.inner
}
///|
pub struct LimitStereo {
inner : Limit
}
///|
pub fn[S : Source] LimitStereo::new(
source : S,
settings : LimitSettings,
) -> LimitStereo {
{ inner: Limit::new(source, settings) }
}
///|
pub fn LimitStereo::inner(self : LimitStereo) -> Limit {
self.inner
}
///|
pub fn LimitStereo::inner_mut(self : LimitStereo) -> Limit {
self.inner
}
///|
pub fn LimitStereo::into_inner(self : LimitStereo) -> Limit {
self.inner
}
///|
pub struct LimitMulti {
inner : Limit
}
///|
pub fn[S : Source] LimitMulti::new(
source : S,
settings : LimitSettings,
) -> LimitMulti {
{ inner: Limit::new(source, settings) }
}
///|
pub fn LimitMulti::inner(self : LimitMulti) -> Limit {
self.inner
}
///|
pub fn LimitMulti::inner_mut(self : LimitMulti) -> Limit {
self.inner
}
///|
pub fn LimitMulti::into_inner(self : LimitMulti) -> Limit {
self.inner
}
///|
pub struct Mix {
inner : DynSource
}
///|
pub fn[A : Source, B : Source] Mix::new(left : A, right : B) -> Mix {
{ inner: mix(left, right) }
}
///|
pub fn Mix::inner(self : Mix) -> DynSource {
self.inner
}
///|
pub fn Mix::inner_mut(self : Mix) -> DynSource {
self.inner
}
///|
pub fn Mix::into_inner(self : Mix) -> DynSource {
self.inner
}
///|
pub struct Repeat {
inner : DynSource
}
///|
pub fn[S : Source] Repeat::new(source : S) -> Repeat {
{ inner: repeat_infinite(source) }
}
///|
pub fn Repeat::inner(self : Repeat) -> DynSource {
self.inner
}
///|
pub fn Repeat::inner_mut(self : Repeat) -> DynSource {
self.inner
}
///|
pub fn Repeat::into_inner(self : Repeat) -> DynSource {
self.inner
}
///|
pub struct SkipDuration {
inner : DynSource
}
///|
pub fn[S : Source] SkipDuration::new(
source : S,
duration : @moon_cpal.Duration,
) -> SkipDuration {
{ inner: skip_duration(source, duration) }
}
///|
pub fn SkipDuration::inner(self : SkipDuration) -> DynSource {
self.inner
}
///|
pub fn SkipDuration::inner_mut(self : SkipDuration) -> DynSource {
self.inner
}
///|
pub fn SkipDuration::into_inner(self : SkipDuration) -> DynSource {
self.inner
}
///|
pub struct Speed {
input : DynSource
factor : Ref[Double]
}
///|
pub fn[S : Source] Speed::new(source : S, ratio : Double) -> Speed {
guard ratio > 0.0 else { panic() }
{ input: to_dyn(source), factor: @ref.new(ratio) }
}
///|
pub fn Speed::set_factor(self : Speed, factor : Double) -> Unit {
guard factor > 0.0 else { panic() }
self.factor.val = factor
}
///|
pub fn Speed::inner(self : Speed) -> DynSource {
self.input
}
///|
pub fn Speed::inner_mut(self : Speed) -> DynSource {
self.input
}
///|
pub fn Speed::into_inner(self : Speed) -> DynSource {
self.input
}
///|
pub struct TakeDuration {
inner : DynSource
requested_duration : @moon_cpal.Duration
requested_samples : Int
remaining_samples : Ref[Int]
filter_fadeout : Ref[Bool]
}
///|
pub fn[S : Source] TakeDuration::new(
source : S,
duration : @moon_cpal.Duration,
) -> TakeDuration {
let inner = to_dyn(source)
let requested_samples = duration_to_sample_count(
duration,
inner.channels(),
inner.sample_rate(),
)
{
inner,
requested_duration: duration,
requested_samples,
remaining_samples: @ref.new(requested_samples),
filter_fadeout: @ref.new(false),
}
}
///|
pub fn TakeDuration::inner(self : TakeDuration) -> DynSource {
self.inner
}
///|
pub fn TakeDuration::inner_mut(self : TakeDuration) -> DynSource {
self.inner
}
///|
pub fn TakeDuration::into_inner(self : TakeDuration) -> DynSource {
self.inner
}
///|
pub fn TakeDuration::set_filter_fadeout(self : TakeDuration) -> Unit {
self.filter_fadeout.val = true
}
///|
pub fn TakeDuration::clear_filter(self : TakeDuration) -> Unit {
self.filter_fadeout.val = false
}
///|
pub struct Zero {
inner : DynSource
}
///|
pub fn Zero::new(channels : ChannelCount, sample_rate : SampleRate) -> Zero {
{ inner: zero(channels, sample_rate) }
}
///|
pub fn Zero::new_samples(
channels : ChannelCount,
sample_rate : SampleRate,
num_samples : Int,
) -> Zero {
{ inner: zero_samples(channels, sample_rate, num_samples) }
}
///|
pub fn Zero::inner(self : Zero) -> DynSource {
self.inner
}
///|
pub fn Zero::inner_mut(self : Zero) -> DynSource {
self.inner
}
///|
pub fn Zero::into_inner(self : Zero) -> DynSource {
self.inner
}
///|
pub struct LinearGainRamp {
inner : DynSource
}
///|
pub fn[S : Source] LinearGainRamp::new(
source : S,
start_gain : Sample,
end_gain : Sample,
duration : @moon_cpal.Duration,
) -> LinearGainRamp {
LinearGainRamp::new_with_clamp(source, start_gain, end_gain, duration, true)
}
///|
pub fn[S : Source] LinearGainRamp::new_with_clamp(
source : S,
start_gain : Sample,
end_gain : Sample,
duration : @moon_cpal.Duration,
clamp_end : Bool,
) -> LinearGainRamp {
{
inner: linear_gain_ramp_with_clamp(
source, start_gain, end_gain, duration, clamp_end,
),
}
}
///|
pub fn LinearGainRamp::inner(self : LinearGainRamp) -> DynSource {
self.inner
}
///|
pub fn LinearGainRamp::inner_mut(self : LinearGainRamp) -> DynSource {
self.inner
}
///|
pub fn LinearGainRamp::into_inner(self : LinearGainRamp) -> DynSource {
self.inner
}
///|
pub struct Spatial {
inner : SpatialSource
}
///|
pub fn[S : Source] Spatial::new(
input : S,
emitter_position : Array[Double],
left_ear : Array[Double],
right_ear : Array[Double],
) -> Spatial {
{ inner: SpatialSource::new(input, emitter_position, left_ear, right_ear) }
}
///|
pub fn Spatial::set_positions(
self : Spatial,
emitter_position : Array[Double],
left_ear : Array[Double],
right_ear : Array[Double],
) -> Unit {
self.inner.set_positions(emitter_position, left_ear, right_ear)
}
///|
pub fn Spatial::inner(self : Spatial) -> SpatialSource {
self.inner
}
///|
pub fn Spatial::inner_mut(self : Spatial) -> SpatialSource {
self.inner
}
///|
pub fn Spatial::into_inner(self : Spatial) -> SpatialSource {
self.inner
}
///|
pub enum Function {
Sine
Triangle
Square
Sawtooth
} derive(Show, Eq)
///|
pub fn Function::sine() -> Function {
Function::Sine
}
///|
pub fn Function::triangle() -> Function {
Function::Triangle
}
///|
pub fn Function::square() -> Function {
Function::Square
}
///|
pub fn Function::sawtooth() -> Function {
Function::Sawtooth
}
///|
pub struct GeneratorFunction {
generator : (Double) -> Sample
}
///|
pub fn GeneratorFunction::new(
generator : (Double) -> Sample,
) -> GeneratorFunction {
{ generator, }
}
///|
pub fn SignalGenerator::from_function(
sample_rate : SampleRate,
frequency : Double,
function : Function,
) -> SignalGenerator {
let sf = match function {
Function::Sine => SignalFunction::Sine
Function::Triangle => SignalFunction::Triangle
Function::Square => SignalFunction::Square
Function::Sawtooth => SignalFunction::Sawtooth
}
SignalGenerator::new(sample_rate, frequency, sf)
}
///|
pub fn SignalGenerator::with_function(
sample_rate : SampleRate,
frequency : Double,
function : Function,
) -> SignalGenerator {
SignalGenerator::from_function(sample_rate, frequency, function)
}
///|
pub fn SignalGenerator::with_generator(
sample_rate : SampleRate,
frequency : Double,
function : GeneratorFunction,
) -> DynSource {
guard sample_rate > 0 else { panic() }
guard frequency >= 0.0 else { panic() }
let phase = @ref.new(0.0)
DynSource::new(
fn() {
let current = phase.val
let step = frequency / Double::from_int(sample_rate)
phase.val = wrap_phase(current + step)
Some((function.generator)(current))
},
1,
sample_rate,
)
}
///|
fn dyn_next(inner : DynSource) -> Sample? {
inner.next()
}
///|
fn dyn_channels(inner : DynSource) -> ChannelCount {
inner.channels()
}
///|
fn dyn_sample_rate(inner : DynSource) -> SampleRate {
inner.sample_rate()
}
///|
pub impl Source for Amplify with next(self : Amplify) {
match self.input.next() {
None => None
Some(v) => Some(v * self.factor.val)
}
}
///|
pub impl Source for Amplify with channels(self : Amplify) {
self.input.channels()
}
///|
pub impl Source for Amplify with sample_rate(self : Amplify) {
self.input.sample_rate()
}
///|
pub impl Source for ChannelVolume with next(self : ChannelVolume) {
let out_channels = self.channel_factors.val.length()
if self.current_channel.val >= out_channels {
self.current_channel.val = 0
self.current_sample.val = None
let in_channels = self.input.channels()
for _ in 0.. ()
Some(s) =>
self.current_sample.val = Some(
self.current_sample.val.unwrap_or(0.0) + s,
)
}
}
self.current_sample.val = self.current_sample.val.map(fn(v) {
v / Double::from_int(in_channels)
})
}
let result = self.current_sample.val.map(fn(v) {
v * self.channel_factors.val[self.current_channel.val]
})
self.current_channel.val += 1
result
}
///|
pub impl Source for ChannelVolume with channels(self : ChannelVolume) {
self.channel_factors.val.length()
}
///|
pub impl Source for ChannelVolume with sample_rate(self : ChannelVolume) {
self.input.sample_rate()
}
///|
pub impl Source for Crossfade with next(self : Crossfade) {
dyn_next(self.inner)
}
///|
pub impl Source for Crossfade with channels(self : Crossfade) {
dyn_channels(self.inner)
}
///|
pub impl Source for Crossfade with sample_rate(self : Crossfade) {
dyn_sample_rate(self.inner)
}
///|
pub impl Source for Delay with next(self : Delay) {
dyn_next(self.inner)
}
///|
pub impl Source for Delay with channels(self : Delay) {
dyn_channels(self.inner)
}
///|
pub impl Source for Delay with sample_rate(self : Delay) {
dyn_sample_rate(self.inner)
}
///|
pub impl Source for Distortion with next(self : Distortion) {
match self.input.next() {
None => None
Some(v) => {
let value = v * self.gain.val
let t = self.threshold.val
if value < -t {
Some(-t)
} else if value > t {
Some(t)
} else {
Some(value)
}
}
}
}
///|
pub impl Source for Distortion with channels(self : Distortion) {
self.input.channels()
}
///|
pub impl Source for Distortion with sample_rate(self : Distortion) {
self.input.sample_rate()
}
///|
pub impl Source for Empty with next(self : Empty) {
dyn_next(self.inner)
}
///|
pub impl Source for Empty with channels(self : Empty) {
dyn_channels(self.inner)
}
///|
pub impl Source for Empty with sample_rate(self : Empty) {
dyn_sample_rate(self.inner)
}
///|
pub impl Source for FadeIn with next(self : FadeIn) {
dyn_next(self.inner)
}
///|
pub impl Source for FadeIn with channels(self : FadeIn) {
dyn_channels(self.inner)
}
///|
pub impl Source for FadeIn with sample_rate(self : FadeIn) {
dyn_sample_rate(self.inner)
}
///|
pub impl Source for FadeOut with next(self : FadeOut) {
dyn_next(self.inner)
}
///|
pub impl Source for FadeOut with channels(self : FadeOut) {
dyn_channels(self.inner)
}
///|
pub impl Source for FadeOut with sample_rate(self : FadeOut) {
dyn_sample_rate(self.inner)
}
///|
pub impl Source for Limit with next(self : Limit) {
match self.input.next() {
None => None
Some(sample) => {
let channels = self.integrators.val.length()
if channels <= 0 {
return Some(sample)
}
let channel = self.position.val % channels
self.position.val = (channel + 1) % channels
let limiter_db = limit_reduction_db(
sample,
self.settings.threshold,
self.settings.knee_width,
)
let release_smoothed = self.release_coeff * self.integrators.val[channel] +
(1.0 - self.release_coeff) * limiter_db
let integrator = if limiter_db > release_smoothed {
limiter_db
} else {
release_smoothed
}
self.integrators.val[channel] = integrator
let peak = self.attack_coeff * self.peaks.val[channel] +
(1.0 - self.attack_coeff) * integrator
self.peaks.val[channel] = peak
Some(sample * db_to_linear(-limit_max_peak(self.peaks.val)))
}
}
}
///|
pub impl Source for Limit with channels(self : Limit) {
self.input.channels()
}
///|
pub impl Source for Limit with sample_rate(self : Limit) {
self.input.sample_rate()
}
///|
pub impl Source for LimitMono with next(self : LimitMono) {
self.inner.next()
}
///|
pub impl Source for LimitMono with channels(self : LimitMono) {
self.inner.channels()
}
///|
pub impl Source for LimitMono with sample_rate(self : LimitMono) {
self.inner.sample_rate()
}
///|
pub impl Source for LimitStereo with next(self : LimitStereo) {
self.inner.next()
}
///|
pub impl Source for LimitStereo with channels(self : LimitStereo) {
self.inner.channels()
}
///|
pub impl Source for LimitStereo with sample_rate(self : LimitStereo) {
self.inner.sample_rate()
}
///|
pub impl Source for LimitMulti with next(self : LimitMulti) {
self.inner.next()
}
///|
pub impl Source for LimitMulti with channels(self : LimitMulti) {
self.inner.channels()
}
///|
pub impl Source for LimitMulti with sample_rate(self : LimitMulti) {
self.inner.sample_rate()
}
///|
pub impl Source for Mix with next(self : Mix) {
dyn_next(self.inner)
}
///|
pub impl Source for Mix with channels(self : Mix) {
dyn_channels(self.inner)
}
///|
pub impl Source for Mix with sample_rate(self : Mix) {
dyn_sample_rate(self.inner)
}
///|
pub impl Source for Repeat with next(self : Repeat) {
dyn_next(self.inner)
}
///|
pub impl Source for Repeat with channels(self : Repeat) {
dyn_channels(self.inner)
}
///|
pub impl Source for Repeat with sample_rate(self : Repeat) {
dyn_sample_rate(self.inner)
}
///|
pub impl Source for SkipDuration with next(self : SkipDuration) {
dyn_next(self.inner)
}
///|
pub impl Source for SkipDuration with channels(self : SkipDuration) {
dyn_channels(self.inner)
}
///|
pub impl Source for SkipDuration with sample_rate(self : SkipDuration) {
dyn_sample_rate(self.inner)
}
///|
pub impl Source for Speed with next(self : Speed) {
self.input.next()
}
///|
pub impl Source for Speed with channels(self : Speed) {
self.input.channels()
}
///|
pub impl Source for Speed with sample_rate(self : Speed) {
let rate = (Double::from_int(self.input.sample_rate()) * self.factor.val).to_int()
if rate <= 0 {
1
} else {
rate
}
}
///|
pub impl Source for TakeDuration with next(self : TakeDuration) {
if self.remaining_samples.val <= 0 {
return None
}
match self.inner.next() {
None => {
self.remaining_samples.val = 0
None
}
Some(v) => {
let out = if self.filter_fadeout.val && self.requested_samples > 0 {
v *
Double::from_int(self.remaining_samples.val) /
Double::from_int(self.requested_samples)
} else {
v
}
self.remaining_samples.val -= 1
Some(out)
}
}
}
///|
pub impl Source for TakeDuration with channels(self : TakeDuration) {
self.inner.channels()
}
///|
pub impl Source for TakeDuration with sample_rate(self : TakeDuration) {
self.inner.sample_rate()
}
///|
pub impl Source for Zero with next(self : Zero) {
dyn_next(self.inner)
}
///|
pub impl Source for Zero with channels(self : Zero) {
dyn_channels(self.inner)
}
///|
pub impl Source for Zero with sample_rate(self : Zero) {
dyn_sample_rate(self.inner)
}
///|
pub impl Source for LinearGainRamp with next(self : LinearGainRamp) {
dyn_next(self.inner)
}
///|
pub impl Source for LinearGainRamp with channels(self : LinearGainRamp) {
dyn_channels(self.inner)
}
///|
pub impl Source for LinearGainRamp with sample_rate(self : LinearGainRamp) {
dyn_sample_rate(self.inner)
}
///|
pub fn Buffered::next(self : Buffered) -> Sample? {
self.inner.next()
}
///|
pub fn Buffered::channels(self : Buffered) -> ChannelCount {
self.inner.channels()
}
///|
pub fn Buffered::sample_rate(self : Buffered) -> SampleRate {
self.inner.sample_rate()
}
///|
pub impl Source for Buffered with next(self : Buffered) {
self.next()
}
///|
pub impl Source for Buffered with channels(self : Buffered) {
self.channels()
}
///|
pub impl Source for Buffered with sample_rate(self : Buffered) {
self.sample_rate()
}
///|
pub fn Spatial::next(self : Spatial) -> Sample? {
self.inner.next()
}
///|
pub fn Spatial::channels(self : Spatial) -> ChannelCount {
self.inner.channels()
}
///|
pub fn Spatial::sample_rate(self : Spatial) -> SampleRate {
self.inner.sample_rate()
}
///|
pub impl Source for Spatial with next(self : Spatial) {
self.next()
}
///|
pub impl Source for Spatial with channels(self : Spatial) {
self.channels()
}
///|
pub impl Source for Spatial with sample_rate(self : Spatial) {
self.sample_rate()
}
///|
pub impl Source for Amplify with current_span_len(_self : Amplify) {
_self.inner().current_span_len()
}
///|
pub impl Source for Amplify with total_duration(_self : Amplify) {
_self.inner().total_duration()
}
///|
pub impl Source for Amplify with try_seek(
_self : Amplify,
pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
_self.inner().try_seek(pos)
}
///|
pub impl Source for ChannelVolume with current_span_len(_self : ChannelVolume) {
_self.inner().current_span_len()
}
///|
pub impl Source for ChannelVolume with total_duration(_self : ChannelVolume) {
_self.inner().total_duration()
}
///|
pub impl Source for ChannelVolume with try_seek(
_self : ChannelVolume,
pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
_self.inner().try_seek(pos)
}
///|
pub impl Source for Crossfade with current_span_len(_self : Crossfade) {
_self.inner().current_span_len()
}
///|
pub impl Source for Crossfade with total_duration(_self : Crossfade) {
_self.inner().total_duration()
}
///|
pub impl Source for Crossfade with try_seek(
_self : Crossfade,
pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
_self.inner().try_seek(pos)
}
///|
pub impl Source for Delay with current_span_len(_self : Delay) {
_self.inner().current_span_len()
}
///|
pub impl Source for Delay with total_duration(_self : Delay) {
_self.inner().total_duration()
}
///|
pub impl Source for Delay with try_seek(
_self : Delay,
pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
_self.inner().try_seek(pos)
}
///|
pub impl Source for Distortion with current_span_len(_self : Distortion) {
_self.inner().current_span_len()
}
///|
pub impl Source for Distortion with total_duration(_self : Distortion) {
_self.inner().total_duration()
}
///|
pub impl Source for Distortion with try_seek(
_self : Distortion,
pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
_self.inner().try_seek(pos)
}
///|
pub impl Source for Empty with current_span_len(_self : Empty) {
_self.inner().current_span_len()
}
///|
pub impl Source for Empty with total_duration(_self : Empty) {
_self.inner().total_duration()
}
///|
pub impl Source for Empty with try_seek(
_self : Empty,
pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
_self.inner().try_seek(pos)
}
///|
pub impl Source for FadeIn with current_span_len(_self : FadeIn) {
_self.inner().current_span_len()
}
///|
pub impl Source for FadeIn with total_duration(_self : FadeIn) {
_self.inner().total_duration()
}
///|
pub impl Source for FadeIn with try_seek(
_self : FadeIn,
pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
_self.inner().try_seek(pos)
}
///|
pub impl Source for FadeOut with current_span_len(_self : FadeOut) {
_self.inner().current_span_len()
}
///|
pub impl Source for FadeOut with total_duration(_self : FadeOut) {
_self.inner().total_duration()
}
///|
pub impl Source for FadeOut with try_seek(
_self : FadeOut,
pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
_self.inner().try_seek(pos)
}
///|
pub impl Source for Limit with current_span_len(_self : Limit) {
_self.input.current_span_len()
}
///|
pub impl Source for Limit with total_duration(_self : Limit) {
_self.input.total_duration()
}
///|
pub impl Source for Limit with try_seek(
_self : Limit,
pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
_self.input.try_seek(pos)
_self.reset_state()
}
///|
pub impl Source for LimitMono with current_span_len(_self : LimitMono) {
_self.inner.current_span_len()
}
///|
pub impl Source for LimitMono with total_duration(_self : LimitMono) {
_self.inner.total_duration()
}
///|
pub impl Source for LimitMono with try_seek(
_self : LimitMono,
pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
_self.inner.try_seek(pos)
}
///|
pub impl Source for LimitStereo with current_span_len(_self : LimitStereo) {
_self.inner.current_span_len()
}
///|
pub impl Source for LimitStereo with total_duration(_self : LimitStereo) {
_self.inner.total_duration()
}
///|
pub impl Source for LimitStereo with try_seek(
_self : LimitStereo,
pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
_self.inner.try_seek(pos)
}
///|
pub impl Source for LimitMulti with current_span_len(_self : LimitMulti) {
_self.inner.current_span_len()
}
///|
pub impl Source for LimitMulti with total_duration(_self : LimitMulti) {
_self.inner.total_duration()
}
///|
pub impl Source for LimitMulti with try_seek(
_self : LimitMulti,
pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
_self.inner.try_seek(pos)
}
///|
pub impl Source for Mix with current_span_len(_self : Mix) {
_self.inner().current_span_len()
}
///|
pub impl Source for Mix with total_duration(_self : Mix) {
_self.inner().total_duration()
}
///|
pub impl Source for Mix with try_seek(_self : Mix, pos : @moon_cpal.Duration) -> Unit raise SeekError {
_self.inner().try_seek(pos)
}
///|
pub impl Source for Repeat with current_span_len(_self : Repeat) {
_self.inner().current_span_len()
}
///|
pub impl Source for Repeat with total_duration(_self : Repeat) {
_self.inner().total_duration()
}
///|
pub impl Source for Repeat with try_seek(
_self : Repeat,
pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
_self.inner().try_seek(pos)
}
///|
pub impl Source for SkipDuration with current_span_len(_self : SkipDuration) {
_self.inner().current_span_len()
}
///|
pub impl Source for SkipDuration with total_duration(_self : SkipDuration) {
_self.inner().total_duration()
}
///|
pub impl Source for SkipDuration with try_seek(
_self : SkipDuration,
pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
_self.inner().try_seek(pos)
}
///|
pub impl Source for Speed with current_span_len(_self : Speed) {
_self.inner().current_span_len()
}
///|
pub impl Source for Speed with total_duration(_self : Speed) {
_self
.inner()
.total_duration()
.map(fn(d) { duration_div_ratio_floor(d, _self.factor.val) })
}
///|
pub impl Source for Speed with try_seek(
_self : Speed,
pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
_self.inner().try_seek(duration_mul_ratio_floor(pos, _self.factor.val))
}
///|
pub impl Source for TakeDuration with current_span_len(_self : TakeDuration) {
let rem = if _self.remaining_samples.val <= 0 {
0
} else {
_self.remaining_samples.val
}
match _self.inner().current_span_len() {
None => Some(rem)
Some(v) => Some(if v < rem { v } else { rem })
}
}
///|
pub impl Source for TakeDuration with total_duration(_self : TakeDuration) {
_self
.inner()
.total_duration()
.map(fn(v) { duration_min(v, _self.requested_duration) })
}
///|
pub impl Source for TakeDuration with try_seek(
_self : TakeDuration,
pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
_self.inner().try_seek(pos)
let target = sample_index_from_duration(
pos,
_self.inner().channels(),
_self.inner().sample_rate(),
)
_self.remaining_samples.val = if target >= _self.requested_samples {
0
} else {
_self.requested_samples - target
}
}
///|
pub impl Source for Zero with current_span_len(_self : Zero) {
_self.inner().current_span_len()
}
///|
pub impl Source for Zero with total_duration(_self : Zero) {
_self.inner().total_duration()
}
///|
pub impl Source for Zero with try_seek(_self : Zero, pos : @moon_cpal.Duration) -> Unit raise SeekError {
_self.inner().try_seek(pos)
}
///|
pub impl Source for LinearGainRamp with current_span_len(_self : LinearGainRamp) {
_self.inner().current_span_len()
}
///|
pub impl Source for LinearGainRamp with total_duration(_self : LinearGainRamp) {
_self.inner().total_duration()
}
///|
pub impl Source for LinearGainRamp with try_seek(
_self : LinearGainRamp,
pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
_self.inner().try_seek(pos)
}
///|
pub impl Source for Buffered with current_span_len(_self : Buffered) {
_self.inner().current_span_len()
}
///|
pub impl Source for Buffered with total_duration(_self : Buffered) {
_self.inner().total_duration()
}
///|
pub impl Source for Buffered with try_seek(
_self : Buffered,
pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
source_default_try_seek(pos)
}
///|
pub impl Source for Spatial with current_span_len(_self : Spatial) {
_self.inner().current_span_len()
}
///|
pub impl Source for Spatial with total_duration(_self : Spatial) {
_self.inner().total_duration()
}
///|
pub impl Source for Spatial with try_seek(
_self : Spatial,
pos : @moon_cpal.Duration,
) -> Unit raise SeekError {
_self.inner().try_seek(pos)
}