use super::audionode::*;
use super::buffer::*;
use super::combinator::*;
use super::math::*;
use super::setting::*;
use super::signal::*;
use super::*;
use core::marker::PhantomData;
use numeric_array::*;
#[derive(Default, Clone)]
pub struct Envelope<F, E, R>
where
F: Real,
E: FnMut(F) -> R + Clone + Send + Sync,
R: ConstantFrame<Sample = F>,
R::Size: Size<F> + Size<f32>,
{
envelope: E,
t: F,
t_0: F,
t_1: F,
t_hash: u64,
value_0: Frame<f32, R::Size>,
value_1: Frame<f32, R::Size>,
value: Frame<f32, R::Size>,
value_d: Frame<f32, R::Size>,
interval: F,
sample_duration: F,
hash: u64,
}
impl<F, E, R> Envelope<F, E, R>
where
F: Real,
E: FnMut(F) -> R + Clone + Send + Sync,
R: ConstantFrame<Sample = F>,
R::Size: Size<F> + Size<f32>,
{
pub fn new(interval: F, envelope: E) -> Self {
assert!(interval > F::zero());
let mut node = Self {
envelope,
t: F::zero(),
t_0: F::zero(),
t_1: F::zero(),
t_hash: 0,
value_0: Frame::default(),
value_1: Frame::default(),
value: Frame::default(),
value_d: Frame::default(),
interval,
sample_duration: F::zero(),
hash: 0,
};
node.set_sample_rate(DEFAULT_SR);
node.reset();
node
}
fn next_segment(&mut self) {
self.t_0 = self.t_1;
self.value_0 = self.value_1.clone();
let next_interval = lerp(
F::from_f32(0.75),
F::from_f32(1.25),
convert(rnd1(self.t_hash)),
) * self.interval;
self.t_1 = self.t_0 + next_interval;
let value_1: Frame<_, _> = (self.envelope)(self.t_1).frame();
self.value_1 = Frame::generate(|i| convert(value_1[i]));
self.t_hash = self
.t_hash
.wrapping_mul(6364136223846793005)
.wrapping_add(1);
let u = delerp(self.t_0, self.t_1, self.t);
self.value = Frame::generate(|i| lerp(self.value_0[i], self.value_1[i], u.to_f32()));
let samples = next_interval / self.sample_duration;
self.value_d = Frame::generate(|i| (self.value_1[i] - self.value_0[i]) / samples.to_f32());
}
}
impl<F, E, R> AudioNode for Envelope<F, E, R>
where
F: Real,
E: FnMut(F) -> R + Clone + Send + Sync,
R: ConstantFrame<Sample = F>,
R::Size: Size<F> + Size<f32>,
{
const ID: u64 = 14;
type Inputs = typenum::U0;
type Outputs = R::Size;
fn reset(&mut self) {
self.t = F::zero();
self.t_0 = F::zero();
self.t_1 = F::zero();
self.t_hash = self.hash;
let value_0: Frame<_, _> = (self.envelope)(self.t_0).frame();
self.value_0 = Frame::generate(|i| convert(value_0[i]));
self.value_1 = self.value_0.clone();
}
fn set_sample_rate(&mut self, sample_rate: f64) {
self.sample_duration = convert(1.0 / sample_rate);
}
#[inline]
fn tick(&mut self, _input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
if self.t >= self.t_1 {
self.next_segment();
}
let output = self.value.clone();
self.value += &self.value_d;
self.t += self.sample_duration;
output
}
fn process(&mut self, size: usize, _input: &BufferRef, output: &mut BufferMut) {
if self.t >= self.t_1 {
self.next_segment();
}
let mut i = 0;
while i < size {
let segment_samples_left =
((self.t_1 - self.t) / self.sample_duration).ceil().to_i64() as usize;
let loop_samples = Num::min(size - i, segment_samples_left);
for channel in 0..self.outputs() {
let mut value = self.value[channel];
let delta = self.value_d[channel];
for o in output.channel_f32_mut(channel)[i..i + loop_samples].iter_mut() {
*o = value.to_f32();
value += delta;
}
self.value[channel] = value;
}
i += loop_samples;
self.t += F::new(loop_samples as i64) * self.sample_duration;
if loop_samples == segment_samples_left {
self.next_segment();
}
}
}
fn set(&mut self, setting: Setting) {
if let Parameter::Interval(time) = setting.parameter() {
self.interval = F::from_f32(*time);
}
}
fn set_hash(&mut self, hash: u64) {
self.hash = hash;
self.t_hash = hash;
}
fn route(&mut self, input: &SignalFrame, _frequency: f64) -> SignalFrame {
Routing::Generator(0.0).route(input, self.outputs())
}
}
#[derive(Default, Clone)]
pub struct EnvelopeIn<F, E, I, R>
where
F: Real,
E: FnMut(F, &Frame<f32, I>) -> R + Clone + Send + Sync,
I: Size<f32>,
R: ConstantFrame<Sample = F>,
R::Size: Size<F> + Size<f32>,
{
envelope: E,
t: F,
t_0: F,
t_1: F,
t_hash: u64,
value_0: Frame<f32, R::Size>,
value_1: Frame<f32, R::Size>,
value: Frame<f32, R::Size>,
value_d: Frame<f32, R::Size>,
interval: F,
sample_duration: F,
hash: u64,
_marker: PhantomData<I>,
}
impl<F, E, I, R> EnvelopeIn<F, E, I, R>
where
F: Real,
E: FnMut(F, &Frame<f32, I>) -> R + Clone + Send + Sync,
I: Size<f32>,
R: ConstantFrame<Sample = F>,
R::Size: Size<F> + Size<f32>,
{
pub fn new(interval: F, envelope: E) -> Self {
assert!(interval > F::zero());
let mut node = Self {
envelope,
t: F::zero(),
t_0: F::zero(),
t_1: F::zero(),
t_hash: 0,
value_0: Frame::default(),
value_1: Frame::default(),
value: Frame::default(),
value_d: Frame::default(),
interval,
sample_duration: F::zero(),
hash: 0,
_marker: PhantomData,
};
node.set_sample_rate(DEFAULT_SR);
node.reset();
node
}
fn next_segment(&mut self, input: &Frame<f32, I>) {
if self.t_0 == F::zero() && self.t_1 == F::zero() {
let value_0: Frame<_, _> = (self.envelope)(self.t_0, input).frame();
self.value_0 = Frame::generate(|i| convert(value_0[i]));
} else {
self.t_0 = self.t_1;
self.value_0 = self.value_1.clone();
}
let next_interval = lerp(
F::from_f32(0.75),
F::from_f32(1.25),
convert(rnd1(self.t_hash)),
) * self.interval;
self.t_1 = self.t_0 + next_interval;
let value_1: Frame<_, _> = (self.envelope)(self.t_1, input).frame();
self.value_1 = Frame::generate(|i| convert(value_1[i]));
self.t_hash = self
.t_hash
.wrapping_mul(6364136223846793005)
.wrapping_add(1);
let u = delerp(self.t_0, self.t_1, self.t);
self.value = Frame::generate(|i| lerp(self.value_0[i], self.value_1[i], u.to_f32()));
let samples = next_interval / self.sample_duration;
self.value_d = Frame::generate(|i| (self.value_1[i] - self.value_0[i]) / samples.to_f32());
}
}
impl<F, E, I, R> AudioNode for EnvelopeIn<F, E, I, R>
where
F: Real,
E: FnMut(F, &Frame<f32, I>) -> R + Clone + Send + Sync,
I: Size<f32>,
R: ConstantFrame<Sample = F>,
R::Size: Size<F> + Size<f32>,
{
const ID: u64 = 53;
type Inputs = I;
type Outputs = R::Size;
fn reset(&mut self) {
self.t = F::zero();
self.t_0 = F::zero();
self.t_1 = F::zero();
self.t_hash = self.hash;
}
fn set_sample_rate(&mut self, sample_rate: f64) {
self.sample_duration = convert(1.0 / sample_rate);
}
#[inline]
fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
if self.t >= self.t_1 {
self.next_segment(input);
}
let output = self.value.clone();
self.value += &self.value_d;
self.t += self.sample_duration;
output
}
fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
if size == 0 {
return;
}
if self.t >= self.t_1 {
self.next_segment(&Frame::generate(|j| input.at_f32(j, 0)));
}
let mut i = 0;
while i < size {
let segment_samples_left =
ceil((self.t_1 - self.t) / self.sample_duration).to_i64() as usize;
let loop_samples = min(size - i, segment_samples_left);
for channel in 0..self.outputs() {
let mut value = self.value[channel];
let delta = self.value_d[channel];
for o in output.channel_f32_mut(channel)[i..i + loop_samples].iter_mut() {
*o = value.to_f32();
value += delta;
}
self.value[channel] = value;
}
i += loop_samples;
self.t += F::new(loop_samples as i64) * self.sample_duration;
if loop_samples == segment_samples_left && i < size {
self.next_segment(&Frame::generate(|j| input.at_f32(j, i)));
}
}
}
fn set(&mut self, setting: Setting) {
if let Parameter::Interval(time) = setting.parameter() {
self.interval = F::from_f32(*time);
}
}
fn set_hash(&mut self, hash: u64) {
self.hash = hash;
self.t_hash = hash;
}
fn route(&mut self, input: &SignalFrame, _frequency: f64) -> SignalFrame {
Routing::Generator(0.0).route(input, self.outputs())
}
}