
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
audio-effect
Advanced tools
Audio effects – modulation, dynamics, delay, spatial, utility, distortion
Canonical audio effect implementations.
npm install audio-effect
// import everything
import * as fx from 'audio-effect'
// import by category
import { phaser, flanger, chorus, wah, autoWah, pitchShifter } from 'audio-effect/modulation'
import { compressor, limiter, gate, envelope, expander } from 'audio-effect/dynamics'
import { delay, multitap, pingPong, reverb } from 'audio-effect/delay'
import { distortion, bitcrusher } from 'audio-effect/distortion'
import { stereoWidener, haas, panner } from 'audio-effect/spatial'
import { gain, mixer, slewLimiter, noiseShaping } from 'audio-effect/utility'
All effects share one shape:
effect(buffer, params) // → buffer (modified in-place)
Takes a Float32Array/Float64Array, modifies it in-place, returns it. Pass the same params object on every call — internal state (_phase, _env, etc.) persists across blocks automatically:
let params = { rate: 1, depth: 0.7, fc: 1000, fs: 44100 }
for (let buf of stream) phaser(buf, params)
Spatial effects take two channels and return [left, right]:
stereoWidener(left, right, { width: 1.5 }) // → [left, right]
haas(left, right, { time: 0.02, fs: 44100 }) // → [left, right]
panner(left, right, { pan: -0.5 }) // → [left, right]
LFO-driven effects that vary a parameter periodically.
Cascade of swept allpass filters creating moving notches and peaks.
rate LFO rate in Hz (default 0.5) · depth sweep depth 0–1 (default 0.7) · stages allpass stages (default 4) · feedback 0–1 (default 0.5) · fc center frequency Hz (default 1000) · fs sample rate
import { phaser } from 'audio-effect/modulation'
let p = { rate: 0.5, depth: 0.7, stages: 4, feedback: 0.5, fc: 1000, fs: 44100 }
for (let buf of stream) phaser(buf, p)
Use when: electric guitar, synth pads, vintage phase effects
Not for: spatial positioning (use stereoWidener or haas)
Modulated short delay (1–10 ms) with feedback — creates comb filter sweep.
rate LFO rate in Hz (default 0.3) · depth modulation depth 0–1 (default 0.7) · delay center delay in ms (default 3) · feedback 0–1 (default 0.5) · fs sample rate
import { flanger } from 'audio-effect/modulation'
let p = { rate: 0.3, depth: 0.7, delay: 3, feedback: 0.5, fs: 44100 }
for (let buf of stream) flanger(buf, p)
Use when: jet sweeps, metallic modulation, guitar/bass
Not for: subtle pitch modulation (use vibrato)
Multiple detuned delay voices layered over dry signal — ensemble thickening.
rate LFO rate in Hz (default 1.5) · depth modulation depth 0–1 (default 0.5) · delay center delay in ms (default 20) · voices number of chorus voices (default 3) · fs sample rate
import { chorus } from 'audio-effect/modulation'
let p = { rate: 1.5, depth: 0.5, delay: 20, voices: 3, fs: 44100 }
for (let buf of stream) chorus(buf, p)
Use when: thickening strings, vocals, synth pads
Not for: transparent processing (adds modulation artifacts)
Swept resonant bandpass filter — auto (LFO) or fixed frequency mode.
rate LFO rate in Hz (default 1.5) · depth sweep depth 0–1 (default 0.8) · fc center frequency Hz (default 1000) · Q resonance (default 5) · mode 'auto' LFO or 'manual' fixed (default 'auto') · fs sample rate
import { wah } from 'audio-effect/modulation'
let p = { rate: 1.5, depth: 0.8, fc: 1000, Q: 5, fs: 44100 }
for (let buf of stream) wah(buf, p)
Use when: classic wah sound, filter sweeps
Not for: signal-driven wah (use autoWah)
Amplitude modulation via LFO — periodic volume pulsing.
rate LFO rate in Hz (default 5) · depth modulation depth 0–1 (default 0.5) · fs sample rate
import { tremolo } from 'audio-effect/modulation'
let p = { rate: 5, depth: 0.7, fs: 44100 }
for (let buf of stream) tremolo(buf, p)
Use when: vintage amp tremolo, rhythmic pulsing, guitar effects
Not for: pitch modulation (use vibrato)
Pitch modulation via modulated delay line — periodic pitch wobble.
rate LFO rate in Hz (default 5) · depth delay modulation depth in seconds (default 0.003) · fs sample rate
import { vibrato } from 'audio-effect/modulation'
let p = { rate: 5, depth: 0.003, fs: 44100 }
for (let buf of stream) vibrato(buf, p)
Use when: vocal vibrato, string wobble, instrument simulation
Not for: amplitude variation (use tremolo)
Multiplies signal by a carrier oscillator — produces sum and difference frequencies.
fc carrier frequency Hz (default 440) · mix wet/dry 0–1 (default 1) · fs sample rate
import { ringMod } from 'audio-effect/modulation'
let p = { fc: 300, mix: 1, fs: 44100 }
for (let buf of stream) ringMod(buf, p)
Use when: metallic/robotic tones, experimental textures, AM synthesis
Not for: clean frequency shifting
Granular OLA pitch shifting via varispeed read with crossfade grain boundaries.
shift pitch ratio (default 1.5 · 2 = +octave · 0.5 = −octave) · grain grain size in samples (default 2048) · fs sample rate
import { pitchShifter } from 'audio-effect/modulation'
let p = { shift: 1.5, grain: 2048, fs: 44100 }
for (let buf of stream) pitchShifter(buf, p)
Use when: harmonizer, octave up/down, pitch correction
Not for: high-quality transposition (use phase vocoder for that)
Envelope follower drives a resonant bandpass filter — signal level controls the sweep.
base minimum cutoff Hz (default 300) · range sweep range Hz (default 3000) · Q resonance (default 5) · attack envelope attack seconds (default 0.002) · release envelope release seconds (default 0.1) · sens input sensitivity multiplier (default 2) · fs sample rate
import { autoWah } from 'audio-effect/modulation'
let p = { base: 300, range: 3000, Q: 5, sens: 2, fs: 44100 }
for (let buf of stream) autoWah(buf, p)
Use when: funk guitar, touch-sensitive filter sweeps, envelope filter
Not for: LFO-driven wah (use wah with mode: 'auto')
Gain-control effects that respond to signal level.
Reduces dynamic range above threshold — feedforward with envelope follower and soft knee.
threshold dB (default −20) · ratio compression ratio (default 4) · attack seconds (default 0.003) · release seconds (default 0.1) · knee soft knee width dB (default 0) · makeupGain dB (default 0) · fs sample rate
import { compressor } from 'audio-effect/dynamics'
let p = { threshold: -18, ratio: 4, attack: 0.003, release: 0.1, fs: 44100 }
for (let buf of stream) compressor(buf, p)
Use when: taming peaks, bus glue, leveling vocals
Not for: hard limiting (use limiter)
Hard ceiling — infinite-ratio compressor, clamps peaks to threshold.
threshold linear amplitude ceiling (default 0.9) · release seconds (default 0.1) · fs sample rate
import { limiter } from 'audio-effect/dynamics'
let p = { threshold: 0.9, release: 0.05, fs: 44100 }
for (let buf of stream) limiter(buf, p)
Use when: preventing clipping, master bus ceiling, broadcast compliance
Not for: transparent dynamic control (use compressor)
Attenuates signal below threshold — cleans up noise in pauses.
threshold dB (default −40) · range attenuation when closed dB (default −80) · attack seconds (default 0.001) · release seconds (default 0.05) · fs sample rate
import { gate } from 'audio-effect/dynamics'
let p = { threshold: -30, range: -80, attack: 0.001, release: 0.05, fs: 44100 }
for (let buf of stream) gate(buf, p)
Use when: removing mic bleed, drum gate, noise floor cleanup
Not for: compression or amplitude control
Rectifies and smooths signal to extract amplitude envelope — outputs envelope as signal.
attack seconds (default 0.01) · release seconds (default 0.1) · fs sample rate
import { envelope } from 'audio-effect/dynamics'
let p = { attack: 0.005, release: 0.05, fs: 44100 }
for (let buf of stream) envelope(buf, p)
// buf now contains the envelope curve
Use when: sidechain source, envelope-controlled parameters, VCA control
Not for: gain reduction (use compressor)
Separately amplifies or attenuates transient (attack) and sustain portions.
attackGain transient multiplier (default 1) · sustainGain sustain multiplier (default 0) · fs sample rate
import { transientShaper } from 'audio-effect/dynamics'
let p = { attackGain: 2, sustainGain: -0.5, fs: 44100 }
for (let buf of stream) transientShaper(buf, p)
Use when: drum punch enhancement, click reduction, transient design
Not for: general dynamic range control
Downward expansion below threshold — attenuates quiet signals, complementing compression.
threshold dB (default −40) · ratio expansion ratio > 1 (default 2) · range maximum attenuation floor dB (default −60) · attack seconds (default 0.001) · release seconds (default 0.1) · fs sample rate
import { expander } from 'audio-effect/dynamics'
let p = { threshold: -40, ratio: 2, range: -60, attack: 0.001, release: 0.1, fs: 44100 }
for (let buf of stream) expander(buf, p)
Transfer function: for each dB < threshold, gainDB = max((ratio−1)×(dB−threshold), range)
| ratio | effect |
|---|---|
| 2 | gentle expansion, doubles apparent dynamic range |
| 4 | aggressive, close to gate behavior |
| ∞ | pure gate |
Use when: subtle noise reduction, dynamic restoration, complementing compression
Not for: hard noise removal (use gate)
Time-based echo and reverberation effects.
Simple delay — dry signal mixed with delayed copy and optional feedback.
time delay time in seconds (default 0.25) · feedback echo decay 0–1 (default 0.3) · mix wet/dry 0–1 (default 0.5) · fs sample rate
import { delay } from 'audio-effect/delay'
let p = { time: 0.25, feedback: 0.4, mix: 0.5, fs: 44100 }
for (let buf of stream) delay(buf, p)
Use when: slap-back echo, rhythmic delays, tape delay emulation
Not for: diffuse reverberation (use reverb)
Multiple independent delay taps at different times with individual gains.
taps array of { time, gain } objects · fs sample rate
import { multitap } from 'audio-effect/delay'
let p = {
taps: [{ time: 0.1, gain: 0.6 }, { time: 0.25, gain: 0.4 }, { time: 0.4, gain: 0.2 }],
fs: 44100
}
for (let buf of stream) multitap(buf, p)
Use when: complex rhythmic echo patterns, vintage tape echo with multiple heads
Not for: simple single echo (use delay)
Cross-fed stereo delay — left echo bounces to right, right to left.
time delay time in seconds (default 0.25) · feedback 0–1 (default 0.3) · mix wet/dry 0–1 (default 0.5) · fs sample rate
import { pingPong } from 'audio-effect/delay'
let p = { time: 0.15, feedback: 0.5, mix: 0.5, fs: 44100 }
for (let [L, R] of stereoStream) pingPong(L, R, p)
Use when: stereo width from delays, spatial depth, rhythmic bounce effects
Not for: mono output
Schroeder reverb — 4 parallel feedback comb filters with LP damping, 2 series allpass diffusers.
decay reverb time 0–1 (default 0.84) · damping high-frequency rolloff 0–1 (default 0.5) · mix wet/dry 0–1 (default 0.3) · fs sample rate
import { reverb } from 'audio-effect/delay'
let p = { decay: 0.84, damping: 0.5, mix: 0.3, fs: 44100 }
for (let buf of stream) reverb(buf, p)
Implementation: 4 parallel comb delays (1277–1523 samples at 44100 Hz), LP filter on feedback path, 2 Schroeder allpass stages (277, 349 samples)
Use when: room ambience, plate reverb character, spatial depth
Not for: convolution reverb accuracy (use an IR-based approach for that)
Non-linear waveshaping effects.
Four waveshaping types: cubic soft clip, hard clip, tanh saturation, and wavefolding.
drive distortion amount 0–1 (default 0.5, maps to 1–10× input gain) · type 'soft' | 'hard' | 'tanh' | 'foldback' (default 'soft') · mix wet/dry 0–1 (default 1) · fs sample rate
import { distortion } from 'audio-effect/distortion'
// Soft saturation
let p = { drive: 0.6, type: 'soft', fs: 44100 }
for (let buf of stream) distortion(buf, p)
// Hard clip
distortion(buf, { drive: 0.8, type: 'hard' })
// Tanh (asymptotically smooth, never clips hard)
distortion(buf, { drive: 0.5, type: 'tanh' })
// Wavefolding (metallic/harsh)
distortion(buf, { drive: 0.7, type: 'foldback' })
| type | character | clamps at ±1 |
|---|---|---|
soft | cubic saturation, smooth knee | yes |
hard | brickwall clip, harsh | yes |
tanh | asymptotically smooth | approaches 1 |
foldback | metallic, complex harmonics | yes |
Use when: guitar overdrive, tube saturation, lo-fi crunch, harmonic enrichment
Not for: transparent limiting (use limiter)
Sample-rate reduction (zero-order hold) + bit-depth quantization.
bits target bit depth 1–24 (default 8) · rate sample rate ratio 0–1 (default 0.25, quarter rate) · fs sample rate
import { bitcrusher } from 'audio-effect/distortion'
// 8-bit, quarter sample rate (lo-fi)
let p = { bits: 8, rate: 0.25, fs: 44100 }
for (let buf of stream) bitcrusher(buf, p)
// Bit depth only, no rate reduction
bitcrusher(buf, { bits: 4, rate: 1 })
Use when: lo-fi aesthetics, game audio, retro console sound, stutter effects
Not for: smooth saturation (use distortion)
Stereo image and positioning effects. All take (left, right, params) and return [left, right].
Mid/side processing to widen or narrow the stereo image.
width 0 = mono, 1 = unchanged, 2 = full side emphasis (default 1.5)
import { stereoWidener } from 'audio-effect/spatial'
let p = { width: 1.5 }
for (let [L, R] of stereoStream) stereoWidener(L, R, p)
Use when: widening narrow mixes, mono-compatibility check (width=0), mastering
Not for: positioning a single source (use panner)
Delays one channel by 1–35 ms — creates phantom stereo from mono source.
time delay in seconds (default 0.02 = 20 ms) · channel 'left' or 'right' (default 'right') · fs sample rate
import { haas } from 'audio-effect/spatial'
let p = { time: 0.015, channel: 'right', fs: 44100 }
for (let [L, R] of stereoStream) haas(L, R, p)
Use when: mono-to-stereo widening, spatial placement, drum room simulation
Not for: large delays (use ping-pong delay instead)
Constant-power stereo panning using cos/sin law.
pan −1 = full left, 0 = center, +1 = full right (default 0)
import { panner } from 'audio-effect/spatial'
let p = { pan: -0.3 }
for (let [L, R] of stereoStream) panner(L, R, p)
Use when: placing sources in the stereo field
Not for: 3D spatial audio
Signal conditioning and mixing tools.
Simple level adjustment in decibels.
dB gain in dB (default 0)
import { gain } from 'audio-effect/utility'
for (let buf of stream) gain(buf, { dB: -6 })
Sums an array of buffers with individual gain multipliers.
channels array of { buffer, gain } objects
import { mixer } from 'audio-effect/utility'
let out = mixer([
{ buffer: drums, gain: 0.8 },
{ buffer: bass, gain: 0.7 },
{ buffer: synth, gain: 0.5 },
])
Use when: combining signals, bus summing, stem mixing
Clips the derivative — limits how fast the signal can change.
rise maximum rise rate in units/second (default 1000) · fall maximum fall rate (default 1000) · fs sample rate
import { slewLimiter } from 'audio-effect/utility'
let p = { rise: 5000, fall: 5000, fs: 44100 }
for (let buf of stream) slewLimiter(buf, p)
Use when: click removal, smoothing control signals, limiting slew on CVs
Not for: dynamic range control
Error-feedback quantization — shapes quantization noise out of the audible band.
bits target bit depth (default 16)
import { noiseShaping } from 'audio-effect/utility'
for (let buf of stream) noiseShaping(buf, { bits: 16 })
Use when: dithering before bit-depth reduction, quantization to lower bit depths
Not for: audio compression (unrelated to lossy codecs)
FAQs
Audio effects – modulation, dynamics, delay, spatial, utility, distortion
We found that audio-effect demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.