use super::audionode::*;
use super::buffer::*;
use super::filter::*;
use super::fir::*;
use super::math::*;
use super::setting::*;
use super::signal::*;
use super::*;
use core::marker::PhantomData;
use funutd::Rnd;
use numeric_array::*;
extern crate alloc;
use alloc::vec::Vec;
#[derive(Default, Clone)]
pub struct Sine<F: Real> {
phase: F,
sample_duration: F,
hash: u64,
initial_phase: Option<F>,
}
impl<F: Real> Sine<F> {
pub fn new() -> Self {
let mut sine = Sine::default();
sine.reset();
sine.set_sample_rate(DEFAULT_SR);
sine
}
pub fn with_phase(initial_phase: f32) -> Self {
let mut sine = Self {
phase: F::zero(),
sample_duration: F::zero(),
hash: 0,
initial_phase: Some(F::from_f32(initial_phase)),
};
sine.reset();
sine.set_sample_rate(DEFAULT_SR);
sine
}
}
impl<F: Real> AudioNode for Sine<F> {
const ID: u64 = 21;
type Inputs = typenum::U1;
type Outputs = typenum::U1;
fn reset(&mut self) {
self.phase = match self.initial_phase {
Some(phase) => phase,
None => convert(rnd1(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> {
let phase = self.phase;
self.phase += F::from_f32(input[0]) * self.sample_duration;
self.phase -= self.phase.floor();
[sin(phase.to_f32() * f32::TAU)].into()
}
fn process(&mut self, size: usize, input: &BufferRef, output: &mut BufferMut) {
let mut phase = self.phase;
for i in 0..full_simd_items(size) {
let element: [f32; SIMD_N] = core::array::from_fn(|j| {
let tmp = phase.to_f32();
phase += F::from_f32(input.at_f32(0, (i << SIMD_S) + j)) * self.sample_duration;
tmp
});
output.set(0, i, (F32x::new(element) * f32::TAU).sin());
}
self.phase = phase - phase.floor();
self.process_remainder(size, input, output);
}
fn set(&mut self, setting: Setting) {
if let Parameter::Phase(phase) = setting.parameter() {
self.initial_phase = Some(F::from_f32(*phase));
}
}
fn set_hash(&mut self, hash: u64) {
self.hash = hash;
self.reset();
}
fn route(&mut self, input: &SignalFrame, _frequency: f64) -> SignalFrame {
super::signal::Routing::Arbitrary(0.0).route(input, self.outputs())
}
}
fn dsf<T: Real>(f: T, d: T, r: T, n: T) -> T {
(sin(f)
- r * sin(f - d)
- pow(r, n + T::one()) * (sin(f + (n + T::one()) * d) - r * sin(f + n * d)))
/ (T::one() + r * r - T::new(2) * r * cos(d))
}
#[derive(Clone)]
pub struct Dsf<N: Size<f32>> {
phase: f32,
roughness: f32,
harmonic_spacing: f32,
sample_duration: f32,
hash: u64,
initial_phase: Option<f32>,
_marker: PhantomData<N>,
}
impl<N: Size<f32>> Dsf<N> {
pub fn new(harmonic_spacing: f32, roughness: f32) -> Self {
let mut node = Self {
phase: 0.0,
roughness,
harmonic_spacing,
sample_duration: 0.0,
hash: 0,
initial_phase: None,
_marker: PhantomData,
};
node.reset();
node.set_sample_rate(DEFAULT_SR);
node.set_roughness(roughness);
node
}
#[inline]
pub fn roughness(&self) -> f32 {
self.roughness
}
#[inline]
pub fn set_roughness(&mut self, roughness: f32) {
self.roughness = clamp(0.0001, 0.9999, roughness);
}
}
impl<N: Size<f32>> AudioNode for Dsf<N> {
const ID: u64 = 55;
type Inputs = N;
type Outputs = typenum::U1;
fn reset(&mut self) {
self.phase = match self.initial_phase {
Some(phase) => phase,
None => convert(rnd1(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 N::USIZE > 1 {
self.set_roughness(input[1]);
}
self.phase += input[0] * self.sample_duration;
self.phase -= self.phase.floor();
let n = floor(22_050.0 / input[0] / self.harmonic_spacing);
Frame::from([dsf(
self.phase * f32::TAU,
self.phase * f32::TAU * self.harmonic_spacing,
self.roughness,
n,
)])
}
fn set(&mut self, setting: Setting) {
match setting.parameter() {
Parameter::Roughness(roughness) => self.set_roughness(*roughness),
Parameter::Phase(phase) => self.initial_phase = Some(*phase),
_ => (),
}
}
fn set_hash(&mut self, hash: u64) {
self.hash = hash;
self.reset();
}
fn route(&mut self, input: &SignalFrame, _frequency: f64) -> SignalFrame {
super::signal::Routing::Arbitrary(0.0).route(input, self.outputs())
}
}
#[derive(Clone)]
pub struct Pluck {
damping: Fir<typenum::U3>,
tuning: Allpole<f32, typenum::U1>,
line: Vec<f32>,
gain: f32,
pos: usize,
hash: u64,
frequency: f32,
sample_rate: f64,
initialized: bool,
}
impl Pluck {
pub fn new(frequency: f32, gain_per_second: f32, high_frequency_damping: f32) -> Self {
Self {
damping: super::prelude::fir3(1.0 - high_frequency_damping).0,
tuning: Allpole::new(1.0),
line: Vec::new(),
gain: pow(gain_per_second.to_f64(), 1.0 / frequency.to_f64()) as f32,
pos: 0,
hash: 0,
frequency,
sample_rate: DEFAULT_SR,
initialized: false,
}
}
fn initialize_line(&mut self) {
let epsilon = 0.2;
let total_delay = self.sample_rate / self.frequency.to_f64() - 1.0;
let loop_delay = floor(total_delay - epsilon);
let allpass_delay = total_delay - loop_delay;
self.tuning.reset();
self.tuning.set_sample_rate(self.sample_rate);
self.tuning.set_delay(allpass_delay as f32);
self.line.resize(loop_delay as usize, 0.0);
let mut rnd = Rnd::from_u64(self.hash);
let mut mean = 0.0;
for i in 0..self.line.len() {
self.line[i] = rnd.f32_in(-1.0, 1.0);
mean += self.line[i].to_f64();
}
mean /= self.line.len() as f64;
for x in self.line.iter_mut() {
*x -= mean as f32;
}
self.pos = 0;
self.initialized = true;
}
}
impl AudioNode for Pluck {
const ID: u64 = 58;
type Inputs = typenum::U1;
type Outputs = typenum::U1;
fn reset(&mut self) {
self.damping.reset();
self.initialized = false;
}
fn set_sample_rate(&mut self, sample_rate: f64) {
if self.sample_rate != sample_rate {
self.sample_rate = sample_rate;
self.damping.set_sample_rate(sample_rate);
self.initialized = false;
}
}
#[inline]
fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
if !self.initialized {
self.initialize_line();
}
let output = self.line[self.pos] * self.gain + input[0];
let output = self.damping.filter_mono(output);
let output = self.tuning.filter_mono(output);
self.line[self.pos] = output;
self.pos += 1;
if self.pos == self.line.len() {
self.pos = 0;
}
[output].into()
}
fn set_hash(&mut self, hash: u64) {
self.hash = hash;
self.initialized = false;
}
fn route(&mut self, input: &SignalFrame, _frequency: f64) -> SignalFrame {
super::signal::Routing::Arbitrary(0.0).route(input, self.outputs())
}
fn allocate(&mut self) {
if !self.initialized {
self.initialize_line();
}
}
}
#[derive(Clone, Default)]
pub struct Rossler {
x: f32,
y: f32,
z: f32,
sr: f32,
hash: u64,
}
impl Rossler {
pub fn new() -> Self {
let mut rossler = Self::default();
rossler.reset();
rossler.set_sample_rate(DEFAULT_SR);
rossler
}
}
impl AudioNode for Rossler {
const ID: u64 = 73;
type Inputs = typenum::U1;
type Outputs = typenum::U1;
fn reset(&mut self) {
self.x = lerp(0.0, 1.0, rnd1(self.hash) as f32);
self.y = 1.0;
self.z = 1.0;
}
fn set_sample_rate(&mut self, sample_rate: f64) {
self.sr = convert(sample_rate);
}
#[inline]
fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
let dx = -self.y - self.z;
let dy = self.x + 0.15 * self.y;
let dz = 0.2 + self.z * (self.x - 10.0);
let dt = 2.91 * input[0] / self.sr;
self.x += dx * dt;
self.y += dy * dt;
self.z += dz * dt;
[self.x * 0.05757].into()
}
fn set_hash(&mut self, hash: u64) {
self.hash = hash;
self.reset();
}
fn route(&mut self, input: &SignalFrame, _frequency: f64) -> SignalFrame {
super::signal::Routing::Arbitrary(0.0).route(input, self.outputs())
}
}
#[derive(Clone, Default)]
pub struct Lorenz {
x: f32,
y: f32,
z: f32,
sr: f32,
hash: u64,
}
impl Lorenz {
pub fn new() -> Self {
let mut lorenz = Self::default();
lorenz.reset();
lorenz.set_sample_rate(DEFAULT_SR);
lorenz
}
}
impl AudioNode for Lorenz {
const ID: u64 = 74;
type Inputs = typenum::U1;
type Outputs = typenum::U1;
fn reset(&mut self) {
self.x = lerp(0.0, 1.0, rnd1(self.hash) as f32);
self.y = 1.0;
self.z = 1.0;
}
fn set_sample_rate(&mut self, sample_rate: f64) {
self.sr = convert(sample_rate);
}
#[inline]
fn tick(&mut self, input: &Frame<f32, Self::Inputs>) -> Frame<f32, Self::Outputs> {
let dx = 10.0 * (self.y - self.x);
let dy = self.x * (28.0 - self.z) - self.y;
let dz = self.x * self.y - (8.0 / 3.0) * self.z;
let dt = input[0] / self.sr;
self.x += dx * dt;
self.y += dy * dt;
self.z += dz * dt;
[self.x * 0.05107].into()
}
fn set_hash(&mut self, hash: u64) {
self.hash = hash;
self.reset();
}
fn route(&mut self, input: &SignalFrame, _frequency: f64) -> SignalFrame {
super::signal::Routing::Arbitrary(0.0).route(input, self.outputs())
}
}
#[derive(Default, Clone)]
pub struct Ramp<F: Float> {
phase: F,
sample_duration: F,
hash: u64,
initial_phase: Option<F>,
}
impl<F: Float> Ramp<F> {
pub fn new() -> Self {
let mut ramp = Self::default();
ramp.reset();
ramp.set_sample_rate(DEFAULT_SR);
ramp
}
pub fn with_phase(initial_phase: f32) -> Self {
let mut ramp = Self {
phase: F::zero(),
sample_duration: F::zero(),
hash: 0,
initial_phase: Some(F::from_f32(initial_phase)),
};
ramp.reset();
ramp.set_sample_rate(DEFAULT_SR);
ramp
}
}
impl<F: Float> AudioNode for Ramp<F> {
const ID: u64 = 94;
type Inputs = typenum::U1;
type Outputs = typenum::U1;
fn reset(&mut self) {
self.phase = match self.initial_phase {
Some(phase) => phase,
None => convert(rnd1(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> {
let phase = self.phase.to_f32();
self.phase += F::from_f32(input[0]) * self.sample_duration;
self.phase -= self.phase.floor();
[phase].into()
}
fn set(&mut self, setting: Setting) {
if let Parameter::Phase(phase) = setting.parameter() {
self.initial_phase = Some(F::from_f32(*phase));
}
}
fn set_hash(&mut self, hash: u64) {
self.hash = hash;
self.reset();
}
fn route(&mut self, input: &SignalFrame, _frequency: f64) -> SignalFrame {
super::signal::Routing::Arbitrary(0.0).route(input, self.outputs())
}
}
#[inline]
fn polyblep<F: Real>(t: F, dt: F) -> F {
if t < dt {
let z = t / dt;
z + z - z * z - F::one()
} else if t > F::one() - dt {
let z = (t - F::one()) / dt;
z + z + z * z + F::one()
} else {
F::zero()
}
}
#[derive(Default, Clone)]
pub struct PolySaw<F: Real> {
phase: F,
sample_duration: F,
hash: u64,
initial_phase: Option<F>,
}
impl<F: Real> PolySaw<F> {
pub fn new() -> Self {
let mut osc = Self::default();
osc.reset();
osc.set_sample_rate(DEFAULT_SR);
osc
}
pub fn with_phase(initial_phase: f32) -> Self {
let mut osc = Self {
phase: F::zero(),
sample_duration: F::zero(),
hash: 0,
initial_phase: Some(F::from_f32(initial_phase)),
};
osc.reset();
osc.set_sample_rate(DEFAULT_SR);
osc
}
}
impl<F: Real> AudioNode for PolySaw<F> {
const ID: u64 = 95;
type Inputs = typenum::U1;
type Outputs = typenum::U1;
fn reset(&mut self) {
self.phase = match self.initial_phase {
Some(phase) => phase,
None => convert(rnd1(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> {
let phase = self.phase;
let delta = F::from_f32(input[0]) * self.sample_duration;
self.phase += delta;
self.phase -= self.phase.floor();
let value = F::new(2) * phase - F::one() - polyblep(phase, delta);
[value.to_f32()].into()
}
fn set(&mut self, setting: Setting) {
if let Parameter::Phase(phase) = setting.parameter() {
self.initial_phase = Some(F::from_f32(*phase));
}
}
fn set_hash(&mut self, hash: u64) {
self.hash = hash;
self.reset();
}
fn route(&mut self, input: &SignalFrame, _frequency: f64) -> SignalFrame {
super::signal::Routing::Arbitrary(0.0).route(input, self.outputs())
}
}
#[derive(Default, Clone)]
pub struct PolySquare<F: Real> {
phase: F,
sample_duration: F,
hash: u64,
initial_phase: Option<F>,
}
impl<F: Real> PolySquare<F> {
pub fn new() -> Self {
let mut osc = Self::default();
osc.reset();
osc.set_sample_rate(DEFAULT_SR);
osc
}
pub fn with_phase(initial_phase: f32) -> Self {
let mut osc = Self {
phase: F::zero(),
sample_duration: F::zero(),
hash: 0,
initial_phase: Some(F::from_f32(initial_phase)),
};
osc.reset();
osc.set_sample_rate(DEFAULT_SR);
osc
}
}
impl<F: Real> AudioNode for PolySquare<F> {
const ID: u64 = 96;
type Inputs = typenum::U1;
type Outputs = typenum::U1;
fn reset(&mut self) {
self.phase = match self.initial_phase {
Some(phase) => phase,
None => convert(rnd1(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> {
let phase = self.phase;
let delta = F::from_f32(input[0]) * self.sample_duration;
self.phase += delta;
self.phase -= self.phase.floor();
let square = if phase < F::from_f32(0.5) {
F::one()
} else {
-F::one()
};
let half = phase - F::from_f32(0.5);
let value = square + polyblep(phase, delta) - polyblep(half - half.floor(), delta);
[value.to_f32()].into()
}
fn set(&mut self, setting: Setting) {
if let Parameter::Phase(phase) = setting.parameter() {
self.initial_phase = Some(F::from_f32(*phase));
}
}
fn set_hash(&mut self, hash: u64) {
self.hash = hash;
self.reset();
}
fn route(&mut self, input: &SignalFrame, _frequency: f64) -> SignalFrame {
super::signal::Routing::Arbitrary(0.0).route(input, self.outputs())
}
}
#[derive(Default, Clone)]
pub struct PolyPulse<F: Real> {
phase: F,
sample_duration: F,
hash: u64,
initial_phase: Option<F>,
}
impl<F: Real> PolyPulse<F> {
pub fn new() -> Self {
let mut osc = Self::default();
osc.reset();
osc.set_sample_rate(DEFAULT_SR);
osc
}
pub fn with_phase(initial_phase: f32) -> Self {
let mut osc = Self {
phase: F::zero(),
sample_duration: F::zero(),
hash: 0,
initial_phase: Some(F::from_f32(initial_phase)),
};
osc.reset();
osc.set_sample_rate(DEFAULT_SR);
osc
}
}
impl<F: Real> AudioNode for PolyPulse<F> {
const ID: u64 = 97;
type Inputs = typenum::U2;
type Outputs = typenum::U1;
fn reset(&mut self) {
self.phase = match self.initial_phase {
Some(phase) => phase,
None => convert(rnd1(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> {
let phase = self.phase;
let delta = F::from_f32(input[0]) * self.sample_duration;
let width = F::from_f32(input[1]);
self.phase += delta;
self.phase -= self.phase.floor();
let square = if phase < width { F::one() } else { -F::one() };
let half = phase - width;
let value = square + polyblep(phase, delta) - polyblep(half - half.floor(), delta);
[value.to_f32()].into()
}
fn set(&mut self, setting: Setting) {
if let Parameter::Phase(phase) = setting.parameter() {
self.initial_phase = Some(F::from_f32(*phase));
}
}
fn set_hash(&mut self, hash: u64) {
self.hash = hash;
self.reset();
}
fn route(&mut self, input: &SignalFrame, _frequency: f64) -> SignalFrame {
super::signal::Routing::Arbitrary(0.0).route(input, self.outputs())
}
}