misceffects.lib

Miscellaneous Effects library. Its official prefix is ef.

This library contains a collection of diverse audio effects and utilities not included in other specialized Faust libraries. It includes filtering, mixing, time based, pitch shifters, and other creative or experimental signal processing components for sound design and musical applications.

The library is organized into 9 sections:

References

Dynamic


(ef.)cubicnl, (ef.)cubicnl_nodc

Cubic nonlinearity distortion. The cubicnl_nodc variant adds a dcblocker on the output. cubicnl is a standard Faust function.

Usage:

_ : cubicnl(drive,offset) : _
_ : cubicnl_nodc(drive,offset) : _

Where:

  • drive: distortion amount, between 0 and 1
  • offset: constant added before nonlinearity to give even harmonics. Note: offset can introduce a nonzero mean - feed cubicnl output to dcblocker to remove this.

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
cubicnl_test = os.osc(440) : ef.cubicnl(0.5, 0.0);

References


(ef.)gate_mono

Mono signal gate. gate_mono is a standard Faust function.

Usage

_ : gate_mono(thresh,att,hold,rel) : _

Where:

  • thresh: dB level threshold above which gate opens (e.g., -60 dB)
  • att: attack time = time constant (sec) for gate to open (e.g., 0.0001 s = 0.1 ms)
  • hold: hold time = time (sec) gate stays open after signal level < thresh (e.g., 0.1 s)
  • rel: release time = time constant (sec) for gate to close (e.g., 0.020 s = 20 ms)

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
gate_mono_test = os.osc(440) : ef.gate_mono(-60, 0.0001, 0.1, 0.02);

References


(ef.)gate_stereo

Stereo signal gates. gate_stereo is a standard Faust function.

Usage

 _,_ : gate_stereo(thresh,att,hold,rel) : _,_

Where:

  • thresh: dB level threshold above which gate opens (e.g., -60 dB)
  • att: attack time = time constant (sec) for gate to open (e.g., 0.0001 s = 0.1 ms)
  • hold: hold time = time (sec) gate stays open after signal level < thresh (e.g., 0.1 s)
  • rel: release time = time constant (sec) for gate to close (e.g., 0.020 s = 20 ms)

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
gate_stereo_test = os.osc(440), os.osc(441) : ef.gate_stereo(-60, 0.0001, 0.1, 0.02);

References


(ef.)gate_gain_mono

The gain signal of the mono gate: the core shared by gate_mono and gate_stereo, which multiply their input by it. Returns a smoothed gain between 0 and 1 following the level of the input signal.

Usage

_ : gate_gain_mono(thresh,att,hold,rel) : _

Where:

  • thresh: dB level threshold above which gate opens (e.g., -60 dB)
  • att: attack time = time constant (sec) for gate to open (e.g., 0.0001 s = 0.1 ms)
  • hold: hold time = time (sec) gate stays open after signal level < thresh (e.g., 0.1 s)
  • rel: release time = time constant (sec) for gate to close (e.g., 0.020 s = 20 ms)

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
gate_gain_mono_test = os.osc(440) : ef.gate_gain_mono(-60, 0.0001, 0.1, 0.02);

Fibonacci


(ef.)fibonacci

Fibonacci system where the current output is the current input plus the sum of the previous N outputs.

Usage

_ : fibonacci(N) : _

Where:

  • N: the Fibonacci system's order, where 2 is standard

Test

ef = library("misceffects.lib");
fibonacci_test = 1 : ef.fibonacci(2);

Example

Generate the famous series: [1, 1, 2, 3, 5, 8, 13, ...]

1. : ba.impulsify : fibonacci(2)

(ef.)fibonacciGeneral

Fibonacci system with customizable coefficients. The order of the system is inferred from the number of coefficients.

Usage

_ : fibonacciGeneral(wave) : _

Where:

  • wave: a waveform such as waveform{1, 1}

Test

ef = library("misceffects.lib");
fibonacciGeneral_test = 1 : ef.fibonacciGeneral(waveform{2, 3});

Example:

Use the update equation y = 2*y' + 3*y'' + 4*y'''

1. : ba.impulsify : fibonacciGeneral(waveform{2, 3, 4})

(ef.)fibonacciSeq

First N numbers of the Fibonacci sequence [1, 1, 2, 3, 5, 8, ...] as parallel channels.

Usage

fibonacciSeq(N) : si.bus(N)

Where:

  • N: The number of Fibonacci numbers to generate as channels.

Test

ef = library("misceffects.lib");
fibonacciSeq_test = ef.fibonacciSeq(5);

Filtering


(ef.)speakerbp

Dirt-simple speaker simulator (overall bandpass eq with observed roll-offs above and below the passband). speakerbp is a standard Faust function.

Low-frequency speaker model = +12 dB/octave slope breaking to flat near f1. Implemented using two dc blockers in series.

High-frequency model = -24 dB/octave slope implemented using a fourth-order Butterworth lowpass.

Usage

_ : speakerbp(f1,f2) : _

Where:

  • f1: low-frequency break point in Hz for the speaker model
  • f2: high-frequency lowpass cutoff in Hz for the speaker model

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
speakerbp_test = os.osc(440) : ef.speakerbp(100.0, 5000.0);

Example

Based on measured Celestion G12 (12" speaker):

speakerbp(130,5000)

(ef.)piano_dispersion_filter

Piano dispersion allpass filter in closed form.

Usage

piano_dispersion_filter(M,B,f0)
_ : piano_dispersion_filter(1,B,f0) : +(totalDelay),_ : fdelay(maxDelay) : _

Where:

  • M: number of first-order allpass sections (compile-time only) Keep below 20. 8 is typical for medium-sized piano strings.
  • B: string inharmonicity coefficient (0.0001 is typical)
  • f0: fundamental frequency in Hz

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
piano_dispersion_filter_test = os.osc(110) : ef.piano_dispersion_filter(4, 0.0001, 110);

Outputs

  • MINUS the estimated delay at f0 of allpass chain in samples, provided in negative form to facilitate subtraction from delay-line length.
  • Output signal from allpass chain

References


(ef.)stereo_width

Stereo Width effect using the Blumlein Shuffler technique. stereo_width is a standard Faust function.

Usage

_,_ : stereo_width(w) : _,_

Where:

  • w: stereo width between 0 and 1

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
stereo_width_test = os.osc(440), os.osc(550) : ef.stereo_width(0.5);

At w=0, the output signal is mono ((left+right)/2 in both channels). At w=1, there is no effect (original stereo image). Thus, w between 0 and 1 varies stereo width from 0 to "original".

References

  • "Applications of Blumlein Shuffling to Stereo Microphone Techniques" Michael A. Gerzon, JAES vol. 42, no. 6, June 1994

(ef.)ms_enc, (ef.)ms_dec

Mid/side encoder and decoder. ms_enc converts a left/right stereo pair into mid = (l+r)/2 and side = (l-r)/2; ms_dec is its exact inverse (l = m+s, r = m-s), so ms_enc : ms_dec is the identity. Process the mid and side channels independently between the two (e.g. compress the mid, EQ or widen the side) for classic M/S mastering.

Usage

_,_ : ms_enc : _,_ // (l,r) to (m,s)
_,_ : ms_dec : _,_ // (m,s) to (l,r)

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
ms_enc_test = os.osc(440), os.osc(550) : ef.ms_enc;
ms_dec_test = os.osc(440), os.osc(550) : ef.ms_enc : ef.ms_dec;

Dither and Noise Shaping

Requantization to a target bit depth, done properly: TPDF dither decorrelates the quantization error from the signal, and error-feedback noise shaping pushes it towards high frequencies where hearing is least sensitive. Use these at the very end of a chain that feeds an integer output format.


(ef.)dither

dither — response plots

TPDF-dithered requantizer to a given bit depth: adds triangular dither of 2 LSB peak-to-peak (the sum of two independent uniform noises), then rounds to the nearest of the 2^nbits levels covering [-1,1). Unlike the plain ba.bitcrusher, the quantization error is decorrelated from the signal: low-level material fades into a constant noise floor instead of developing correlated distortion.

Usage

_ : dither(nbits) : _

Where:

  • nbits: target bit depth (e.g. 16), a constant numerical expression

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
dither_test = os.osc(440)*0.001 : ef.dither(16);

References

  • S.P. Lipshitz, R.A. Wannamaker, J. Vanderkooy, "Quantization and Dither: A Theoretical Survey", JAES vol. 40, no. 5, 1992.

(ef.)dither_shaped

dither_shaped — response plots

TPDF-dithered requantizer with error-feedback noise shaping: the quantization error is fed back through (1-z^-1)^K, giving a noise transfer function that rises at 6*K dB/octave and pushes the error energy towards Nyquist. K = 1 or 2 are the useful orders: higher plain difference orders boost the total noise power faster than hearing benefits (psychoacoustically weighted shapers need dedicated coefficients).

Usage

_ : dither_shaped(K,nbits) : _

Where:

  • K: noise shaping order, 1 or 2 (a constant numerical expression)
  • nbits: target bit depth (e.g. 16), a constant numerical expression

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
dither_shaped_test = os.osc(440)*0.001 : ef.dither_shaped(2, 16);

References

  • S.P. Lipshitz, R.A. Wannamaker, J. Vanderkooy, "Quantization and Dither: A Theoretical Survey", JAES vol. 40, no. 5, 1992.
  • R.A. Wannamaker, "Psychoacoustically Optimal Noise Shaping", JAES vol. 40, no. 7/8, 1992.

Meshes


(ef.)mesh_square

Square Rectangular Digital Waveguide Mesh.

Usage

bus(4*N) : mesh_square(N) : bus(4*N)

Where:

  • N: number of nodes along each edge - a power of two (1,2,4,8,...)

Test

ef = library("misceffects.lib");
mesh_square_test = (1,0.5,-0.5,0.25) : ef.mesh_square(1);

Signal Order In and Out

The mesh is constructed recursively using 2x2 embeddings. Thus, the top level of mesh_square(M) is a block 2x2 mesh, where each block is a mesh(M/2). Let these blocks be numbered 1,2,3,4 in the geometry NW,NE,SW,SE, i.e., as:

    1 2
    3 4

Each block has four vector inputs and four vector outputs, where the length of each vector is M/2. Label the input vectors as Ni,Ei,Wi,Si, i.e., as the inputs from the North, East South, and West, and similarly for the outputs. Then, for example, the upper left input block of M/2 signals is labeled 1Ni. Most of the connections are internal, such as 1Eo -> 2Wi. The 8*(M/2) input signals are grouped in the order:

   1Ni 2Ni
   3Si 4Si
   1Wi 3Wi
   2Ei 4Ei

and the output signals are:

   1No 1Wo
   2No 2Eo
   3So 3Wo
   4So 4Eo

or:

   In: 1No 1Wo 2No 2Eo 3So 3Wo 4So 4Eo
   Out: 1Ni 2Ni 3Si 4Si 1Wi 3Wi 2Ei 4Ei

Thus, the inputs are grouped by direction N,S,W,E, while the outputs are grouped by block number 1,2,3,4, which can also be interpreted as directions NW, NE, SW, SE. A simple program illustrating these orderings is process = mesh_square(2);.

Example

Reflectively terminated mesh impulsed at one corner:

mesh_square_test(N,x) = mesh_square(N)~(busi(4*N,x)) // input to corner
with { 
    busi(N,x) = bus(N) : par(i,N,*(-1)) : par(i,N-1,_), +(x); 
};
process = 1-1' : mesh_square_test(4); // all modes excited forever

In this simple example, the mesh edges are connected as follows:

   1No -> 1Ni, 1Wo -> 2Ni, 2No -> 3Si, 2Eo -> 4Si,
   3So -> 1Wi, 3Wo -> 3Wi, 4So -> 2Ei, 4Eo -> 4Ei

A routing matrix can be used to obtain other connection geometries.

References

Mixing


(ef.)dryWetMixer

Linear dry-wet mixer for an N-inputs, N-outputs effect. The dry and wet gains sum to 1 for all positions, so this mixer is mono-safe but not constant-power: total power dips at the midpoint (each channel at −6 dB).

  • wetAmount = 0 : dry = 1.0 (0 dB), wet = 0
  • wetAmount = 0.5: dry = 0.5 (−6 dB), wet = 0.5 (−6 dB)
  • wetAmount = 1 : dry = 0, wet = 1.0 (0 dB)

Usage

si.bus(inputs(FX)) : dryWetMixer(wetAmount, FX) : si.bus(inputs(FX))

Where:

  • wetAmount: the wet amount (0-1). 0 produces only the dry signal at unity, and 1 produces only the wet signal at unity
  • FX: an arbitrary effect (N inputs and N outputs) to apply to the input bus

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
fi = library("filters.lib");
dryWetMixer_test = os.osc(440) : ef.dryWetMixer(0.5, fi.dcblocker);

(ef.)dryWetMixerConstantPower

Constant-power dry-wet mixer for an N-inputs, N-outputs effect. The dry input is scaled by cos(θ)/√2 and the wet output by sin(θ)/√2, where θ = π*wetAmount/2.

  • wetAmount = 0 : dry = 1/√2 ≈ 0.707 (−3 dB), wet = 0
  • wetAmount = 0.5: dry = 0.5 (−6 dB), wet = 0.5 (−6 dB)
  • wetAmount = 1 : dry = 0, wet = 1/√2 ≈ 0.707 (−3 dB)

Normalization

A standard constant-power crossfade uses bare cos/sin gains, which peak at unity (0 dB) when fully dry or fully wet and dip to 1/√2 (−3 dB) at center. This implementation divides by √2, which makes the mixer mono-safe: the sum of the dry and wet gains is bounded by 1 for all positions:

dryGain + wetGain = (cos θ + sin θ) / √2 ≤ 1

This holds because cos θ + sin θ peaks at √2 (at θ = π/4), and √2/√2 = 1. As a result, if the dry and wet paths carry correlated or in-phase material, their sum can never clip. Total power (dryGain² + wetGain²) is constant at 0.5 for all positions.

Note that the extremes attenuate by −3 dB rather than passing at unity. Use dryWetMixer if unity passthrough at the extremes is required.

Usage

si.bus(inputs(FX)) : dryWetMixerConstantPower(wetAmount, FX) : si.bus(inputs(FX))

Where:

  • wetAmount: the wet amount (0-1). 0 produces only the dry signal at −3 dB and 1 produces only the wet signal at −3 dB
  • FX: an arbitrary effect (N inputs and N outputs) to apply to the input bus

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
fi = library("filters.lib");
dryWetMixerConstantPower_test = os.osc(440) : ef.dryWetMixerConstantPower(0.5, fi.dcblocker);

(ef.)mixLinearClamp

Linear mixer for N buses, each with C channels. The output will be a sum of 2 buses determined by the mixing index mix. 0 produces the first bus, 1 produces the second, and so on. mix is clamped automatically. For example, mixLinearClamp(4, 1, 1) will weight its 4 inputs by (0, 1, 0, 0). Similarly, mixLinearClamp(4, 1, 1.1) will weight its 4 inputs by (0,.9,.1,0).

Usage

si.bus(N*C) : mixLinearClamp(N, C, mix) : si.bus(C)

Where:

  • N: the number of input buses
  • C: the number of channels in each bus
  • mix: the mixing index, continuous in [0;N-1].

Test

ef = library("misceffects.lib");
mixLinearClamp_test = (1,0.5,0,0) : ef.mixLinearClamp(4, 1, 1.2);

(ef.)mixLinearLoop

Linear mixer for N buses, each with C channels. Refer to mixLinearClamp. mix will loop for multiples of N. For example, mixLinearLoop(4, 1, 0) has the same effect as mixLinearLoop(4, 1, -4) and mixLinearLoop(4, 1, 4).

Usage

si.bus(N*C) : mixLinearLoop(N, C, mix) : si.bus(C)

Where:

  • N: the number of input buses
  • C: the number of channels in each bus
  • mix: the mixing index (N-1) selects the last bus, and 0 or N selects the 0th bus.

Test

ef = library("misceffects.lib");
mixLinearLoop_test = (1,0,0,0) : ef.mixLinearLoop(4, 1, -0.3);

(ef.)mixPowerClamp

Constant-power mixer for N buses, each with C channels. The output will be a sum of 2 buses determined by the mixing index mix. 0 produces the first bus, 1 produces the second, and so on. mix is clamped automatically. mixPowerClamp(4, 1, 1) will weight its 4 inputs by (0, 1./sqrt(2), 0, 0). Similarly, mixPowerClamp(4, 1, 1.5) will weight its 4 inputs by (0,.5,.5,0).

Usage

si.bus(N*C) : mixPowerClamp(N, C, mix) : si.bus(C)

Where:

  • N: the number of input buses
  • C: the number of channels in each bus
  • mix: the mixing index, continuous in [0;N-1].

Test

ef = library("misceffects.lib");
mixPowerClamp_test = (1,0,0,0) : ef.mixPowerClamp(4, 1, 1.5);

(ef.)mixPowerLoop

Constant-power mixer for N buses, each with C channels. Refer to mixPowerClamp. mix will loop for multiples of N. For example, mixPowerLoop(4, 1, 0) has the same effect as mixPowerLoop(4, 1, -4) and mixPowerLoop(4, 1, 4).

Usage

si.bus(N*C) : mixPowerLoop(N, C, mix) : si.bus(C)

Where:

  • N: the number of input buses
  • C: the number of channels in each bus
  • mix: the mixing index (N-1) selects the last bus, and 0 or N selects the 0th bus.

Test

ef = library("misceffects.lib");
mixPowerLoop_test = (1,0,0,0) : ef.mixPowerLoop(4, 1, -0.5);

Time Based


(ef.)echo

A simple echo effect. echo is a standard Faust function.

Usage

_ : echo(maxDuration,duration,feedback) : _

Where:

  • maxDuration: the max echo duration in seconds
  • duration: the echo duration in seconds
  • feedback: the feedback coefficient

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
echo_test = os.osc(440) : ef.echo(0.5, 0.25, 0.4);

(ef.)reverseEchoN

Reverse echo effect.

Usage

_ : ef.reverseEchoN(N,delay) : si.bus(N)

Where:

  • N: Number of output channels desired (1 or more), a constant numerical expression
  • delay: echo delay (integer power of 2)

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
reverseEchoN_test = os.osc(440) : ef.reverseEchoN(2, 32);

Demo

_ : dm.reverseEchoN(N) : _,_

Description

The effect uses N instances of reverseDelayRamped at different phases.


(ef.)reverseDelayRamped

Reverse delay with amplitude ramp.

Usage

_ : ef.reverseDelayRamped(delay,phase) : _

Where:

  • delay: echo delay (integer power of 2)
  • phase: float between 0 and 1 giving ramp delay phase*delay

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
reverseDelayRamped_test = os.osc(440) : ef.reverseDelayRamped(32, 0.6);

Demo

_ : ef.reverseDelayRamped(32,0.6) : _,_

(ef.)uniformPanToStereo

Pan nChans channels to the stereo field, spread uniformly left to right.

Usage

si.bus(N) : ef.uniformPanToStereo(N) : _,_

Where:

  • N: Number of input channels to pan down to stereo, a constant numerical expression

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
uniformPanToStereo_test = os.osc(440), os.osc(550), os.osc(660) : ef.uniformPanToStereo(3);

Demo

_,_,_ : ef.uniformPanToStereo(3) : _,_

(ef.)tapeStop

A tape-stop effect, like putting a finger on a vinyl record player.

Usage:

_,_ : tapeStop(2, LAGRANGE_ORDER, MAX_TIME_SAMP, 
              crossfade, gainAlpha, stopAlpha, stopTime, stop) : _,_
_ : tapeStop(1, LAGRANGE_ORDER, MAX_TIME_SAMP, 
             crossfade, gainAlpha, stopAlpha, stopTime, stop) : _

Where:

  • C: The number of input and output channels.
  • LAGRANGE_ORDER: The order of the Lagrange interpolation on the delay line. [2-3] recommended.
  • MAX_TIME_SAMP: Maximum stop time in samples
  • crossfade: A crossfade in samples to apply when resuming normal playback. Crossfade is not applied during the enabling of the tape-stop.
  • gainAlpha: During the tape-stop, lower alpha stays louder longer. Safe values are in the range [.01,2].
  • stopAlpha: stopAlpha==1 represents a linear deceleration (constant force). stopAlpha<1 represents an initially weaker, then stronger force. stopAlpha>1 represents an initially stronger, then weaker force. Safe values are in the range [.01,2].
  • stopTime: Desired duration of the stop time, in samples.
  • stop: When stop becomes positive, the tape-stop effect will start. When stop becomes zero, normal audio will resume via crossfade.

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
tapeStop_test = os.osc(440), os.osc(441) : ef.tapeStop(2, 3, 44100, 128, 1.0, 1.0, 22050, button("stop"));

Pitch Shifting


(ef.)transpose

A simple pitch shifter based on 2 delay lines. transpose is a standard Faust function.

Usage

_ : transpose(w, x, s) : _

Where:

  • w: the window length (samples)
  • x: crossfade duration duration (samples)
  • s: shift (semitones)

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
transpose_test = os.osc(440) : ef.transpose(1024, 512, 7);

(ef.)transpose_windowed

Delay-line pitch shifter with P overlapping Hann-windowed read taps: the windowed-tap refinement of ef.transpose. Each tap sweeps the same w-sample window with a phase offset of 1/P, weighted by an.window_hann of its own phase; since Hann windows at any regular overlap sum to a constant, the crossfade is click-free and equal-amplitude by construction (with s = 0 the output is exactly a delayed copy). P = 2 matches the classic two-tap topology; higher P smears transients less at large shifts.

Usage

_ : transpose_windowed(P, w, s) : _

Where:

  • P: number of overlapping taps, 2 or more (a constant numerical expression)
  • w: window length in samples (up to 65536)
  • s: shift in semitones (positive or negative, may vary at run time)

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
transpose_windowed_test = os.osc(440) : ef.transpose_windowed(2, 1024, 7);

(ef.)granular

Live granulator on an internal delay line: P voices continuously replay Hann-windowed grains of dur seconds taken pos seconds back in the input, each voice offset by 1/P of a grain so the voices overlap into a continuous texture (Hann overlaps sum to a constant: with ratio = 1, jit = 0 the output is exactly the delayed input). The grain start position is latched when each grain begins - pos and jit can move freely without tearing grains. ratio repitches the material inside each grain by resampling (2 = up an octave, 0.5 = down an octave), and jit adds a per-grain random offset to the position for the classic granular cloud.

When repitching tonal material with jit = 0, note that the voices read the source offset by dur/P seconds from one another: if that offset lands near an odd half-period of a source partial, that partial cancels between overlapping grains (ordinary granular phasiness). Choose dur against the material, or add a little jit, to decorrelate the voices.

Usage

_ : granular(P, dur, ratio, pos, jit) : _

Where:

  • P: number of overlapping grain voices, 2 or more (a constant numerical expression)
  • dur: grain duration in seconds
  • ratio: playback speed inside each grain (1 = unchanged pitch)
  • pos: read position in seconds behind the write head
  • jit: random position jitter in seconds, latched per grain

The latched read offset pos + jit + (ratio-1)*dur must stay within the 65536-sample internal line (about 1.36 s at 48 kHz).

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
granular_test = os.osc(440) : ef.granular(4, 0.05, 1.5, 0.2, 0.1);

(ef.)doppler_shift

Pitch shifter for signals with known fundamental frequency. Uses Doppler effect from a continuously ramping delay line, with phase-coherent phasor reset synced to the signal period. Best suited for harmonic/periodic signals like oscillator outputs.

Usage

_ : doppler_shift(freq, ratio) : _

Where:

  • freq: fundamental frequency of the input signal (Hz)
  • ratio: pitch ratio (1.0 = no shift, 2.0 = octave up, 0.5 = octave down)

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
doppler_shift_test = os.sawtooth(220) : ef.doppler_shift(220, 1.5);

References

Saturators


(ef.)softclipQuadratic

Quadratic softclip nonlinearity.

Usage

_ : softclipQuadratic : _

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
softclipQuadratic_test = os.osc(440) : ef.softclipQuadratic;

References

  • U. Zölzer: Digital Audio Signal Processing. John Wiley & Sons Ltd, 2022.

(ef.)wavefold

Wavefolding nonlinearity.

Usage

_ : wavefold(width) : _

Where:

  • width: The width of the folded section [0..1] (float).

Test

ef = library("misceffects.lib");
os = library("oscillators.lib");
wavefold_test = os.osc(440) : ef.wavefold(0.5);