Skip to content

Commit

Permalink
Refactoring.
Browse files Browse the repository at this point in the history
  • Loading branch information
SamiPerttu committed Oct 16, 2024
1 parent 84ed485 commit 3017484
Show file tree
Hide file tree
Showing 19 changed files with 445 additions and 362 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
- `sine_phase`, `ramp_phase` and `ramp_hz_phase` opcodes were removed:
there is a new builder notation for setting the initial phase, for example, `sine().phase(0.0)`.
- New builder notation for setting noise generator seed, for example, `noise().seed(1)`.
- New opcode `biquad_bank()`.
- `BiquadBank` parameters for channel `i` are now set with the syntax `Setting::biquad(...).index(i)`.

### Version 0.20

Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -651,8 +651,8 @@ The following table lists the oscillator opcodes.

The wavetable oscillator is [bandlimited](https://en.wikipedia.org/wiki/Bandlimiting)
with pristine quality.
However, unlike the other types it allocates memory in the form of static wavetables.
The DSF oscillator has similar quality but is somewhat expensive to evaluate.
However, unlike the other types it allocates memory in the form of global wavetables.
The [DSF](https://ccrma.stanford.edu/files/papers/stanm5.pdf) oscillator has similar quality but is somewhat expensive to evaluate.
The PolyBLEP oscillator is a fast approximation with fair quality.

## Working With Waves
Expand Down Expand Up @@ -952,6 +952,7 @@ The following table summarizes the available settings.
| `bandpass_hz` | `center_q` |
| `bell_hz` | `center_q_gain` |
| `biquad` | `biquad` to set biquad coefficients |
| `biquad_bank` | `biquad(a1, a2, b0, b1, b2).index(i)` to set channel `i` coefficients |
| `butterpass_hz` | `center` |
| `constant` | `value` to set scalar value on all channels |
| `dbell_hz` | `center_q_gain` |
Expand Down Expand Up @@ -1121,6 +1122,7 @@ The type parameters in the table refer to the hacker preludes.
| `bell_hz(f, q, gain)` | 1 | 1 | Peaking filter (2nd order) centered at `f` Hz with Q `q` and amplitude gain `gain`. |
| `bell_q(q, gain)` | 2 (audio, frequency) | 1 | Peaking filter (2nd order) with Q `q` and amplitude gain `gain`. |
| `biquad(a1, a2, b0, b1, b2)` | 1 | 1 | Arbitrary [biquad filter](https://en.wikipedia.org/wiki/Digital_biquad_filter) with coefficients in normalized form. |
| `biquad_bank()` | 4/8 | 4/8 | Bank of SIMD accelerated biquad filters with 4 channels in double precision or 8 channels in single precision. |
| `brown()` | - | 1 | [Brown](https://en.wikipedia.org/wiki/Brownian_noise) noise. |
| `branch(x, y)` | `x = y` | `x + y` | Branch into `x` and `y`. Identical with `x ^ y`. |
| `branchf::<U, _, _>(f)`| `f` | `U * f` | Branch into `U` nodes from fractional generator `f`, e.g., `\| x \| resonator_hz(xerp(20.0, 20_000.0, x), xerp(5.0, 5_000.0, x))`. |
Expand Down
4 changes: 2 additions & 2 deletions src/adsr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
//! an `adsr_live()` envelope.
use super::prelude::{clamp01, delerp, envelope2, lerp, shared, var, An, EnvelopeIn, Frame, U1};
use super::Float;
use super::Real;

pub fn adsr_live(
attack: f32,
Expand Down Expand Up @@ -51,7 +51,7 @@ pub fn adsr_live(
})
}

fn ads<F: Float>(attack: F, decay: F, sustain: F, time: F) -> F {
fn ads<F: Real>(attack: F, decay: F, sustain: F, time: F) -> F {
if time < attack {
lerp(F::from_f64(0.0), F::from_f64(1.0), time / attack)
} else {
Expand Down
10 changes: 0 additions & 10 deletions src/audionode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,6 @@ use super::*;
use core::marker::PhantomData;
use num_complex::Complex64;
use numeric_array::typenum::*;
use numeric_array::{ArrayLength, NumericArray};

/// Type-level integer. These are notated as `U0`, `U1`...
pub trait Size<T>: ArrayLength + Sync + Send + Clone {}

impl<T, A: ArrayLength + Sync + Send + Clone> Size<T> for A {}

/// Frames are arrays with a static size used to transport audio data
/// between `AudioNode` instances.
pub type Frame<T, Size> = NumericArray<T, Size>;

/*
Order of type arguments in nodes:
Expand Down
18 changes: 9 additions & 9 deletions src/biquad.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ pub struct BiquadCoefs<F> {
pub b2: F,
}

impl<F: Real> BiquadCoefs<F> {
impl<F: Float> BiquadCoefs<F> {
/// Return settings for a Butterworth lowpass filter.
/// Sample rate is in Hz.
/// Cutoff is the -3 dB point of the filter in Hz.
#[inline]
pub fn butter_lowpass(sample_rate: F, cutoff: F) -> Self {
let c = F::from_f64;
let c = F::from_f32;
let f: F = tan(cutoff * F::PI / sample_rate);
let a0r: F = c(1.0) / (c(1.0) + F::SQRT_2 * f + f * f);
let a1: F = (c(2.0) * f * f - c(2.0)) * a0r;
Expand All @@ -46,7 +46,7 @@ impl<F: Real> BiquadCoefs<F> {
/// The overall gain of the filter is independent of bandwidth.
#[inline]
pub fn resonator(sample_rate: F, center: F, q: F) -> Self {
let c = F::from_f64;
let c = F::from_f32;
let r: F = exp(-F::PI * center / (q * sample_rate));
let a1: F = c(-2.0) * r * cos(F::TAU * center / sample_rate);
let a2: F = r * r;
Expand All @@ -60,7 +60,7 @@ impl<F: Real> BiquadCoefs<F> {
/// Sample rate and cutoff frequency are in Hz.
#[inline]
pub fn lowpass(sample_rate: F, cutoff: F, q: F) -> Self {
let c = F::from_f64;
let c = F::from_f32;
let omega = F::TAU * cutoff / sample_rate;
let alpha = sin(omega) / (c(2.0) * q);
let beta = cos(omega);
Expand All @@ -77,7 +77,7 @@ impl<F: Real> BiquadCoefs<F> {
/// Sample rate and cutoff frequency are in Hz.
#[inline]
pub fn highpass(sample_rate: F, cutoff: F, q: F) -> Self {
let c = F::from_f64;
let c = F::from_f32;
let omega = F::TAU * cutoff / sample_rate;
let alpha = sin(omega) / (c(2.0) * q);
let beta = cos(omega);
Expand All @@ -95,7 +95,7 @@ impl<F: Real> BiquadCoefs<F> {
/// Gain is amplitude gain (`gain` > 0).
#[inline]
pub fn bell(sample_rate: F, center: F, q: F, gain: F) -> Self {
let c = F::from_f64;
let c = F::from_f32;
let omega = F::TAU * center / sample_rate;
let alpha = sin(omega) / (c(2.0) * q);
let beta = cos(omega);
Expand Down Expand Up @@ -129,7 +129,7 @@ impl<F: Real> BiquadCoefs<F> {
}

/// 2nd order IIR filter implemented in normalized Direct Form I.
/// - Setting: coefficients as tuple Parameter::Biquad(a1, a2, b0, b1, b2).
/// - Setting: coefficients as tuple `Setting::biquad(a1, a2, b0, b1, b2)`.
/// - Input 0: input signal.
/// - Output 0: filtered signal.
#[derive(Default, Clone)]
Expand All @@ -142,7 +142,7 @@ pub struct Biquad<F> {
sample_rate: f64,
}

impl<F: Real> Biquad<F> {
impl<F: Float> Biquad<F> {
pub fn new() -> Self {
Self {
sample_rate: DEFAULT_SR,
Expand All @@ -164,7 +164,7 @@ impl<F: Real> Biquad<F> {
}
}

impl<F: Real> AudioNode for Biquad<F> {
impl<F: Float> AudioNode for Biquad<F> {
const ID: u64 = 15;
type Inputs = typenum::U1;
type Outputs = typenum::U1;
Expand Down
Loading

0 comments on commit 3017484

Please sign in to comment.