npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@audio/effect

v2.1.4

Published

Audio effects — umbrella for @audio/effect-* atoms (modulation, delay, distortion, utility)

Readme

@audio/effect

Canonical audio effect implementations.

Modulation Phaser · Flanger · Chorus · Wah-wah · Tremolo · Vibrato · Rotary speaker · Ring mod · Frequency shifter · Pitch shifter · Auto-wah

Dynamics moved to @audio/dynamics

Delay Delay · Multitap · Ping-pong · Reverb

Distortion Distortion / saturation · Exciter · Bitcrusher

Spatial Stereo widener · Haas effect · Panner · Auto-panner

Utility Gain · Mixer · Slew limiter · Noise shaping · Tape stop

Install

npm install @audio/effect
// import everything
import * as fx from '@audio/effect'

// pick what you need
import { phaser, flanger, chorus, wah, autoWah, ringMod, frequencyShifter } from '@audio/effect'
import { delay, multitap, pingPong }                            from '@audio/effect'
import { distortion, exciter, bitcrusher }                      from '@audio/effect'
import { gain, mixer, slewLimiter, noiseShaping }               from '@audio/effect'

// sibling families
import { compressor, limiter, gate, envelope, expander }        from '@audio/dynamics'
import { stereoWidener, haas, panner, autoPanner }              from '@audio/spatial'
import { freeverb, dattorro, convolve }                         from '@audio/reverb'

API

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]

Modulation

LFO-driven effects that vary a parameter periodically.

Phaser

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'

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)

Flanger

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 seconds (default 0.003) · feedback 0–1 (default 0.5) · fs sample rate

import { flanger } from '@audio/effect'

let p = { rate: 0.3, depth: 0.7, delay: 0.003, 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)

Chorus

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 seconds (default 0.02) · voices number of chorus voices (default 3) · fs sample rate

import { chorus } from '@audio/effect'

let p = { rate: 1.5, depth: 0.5, delay: 0.02, 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)

Wah-wah

Swept resonant bandpass filter — auto (LFO) or fixed frequency mode.

rate LFO rate in Hz (default 1.5) · depth sweep depth in octaves, 0–3 (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'

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)

Tremolo

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'

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)

Vibrato

Pitch modulation via modulated delay line — periodic pitch wobble.

rate LFO rate in Hz (default 5) · depth modulation depth 0–1, scales a max ~6ms delay-time swing (default 0.5) · fs sample rate

import { vibrato } from '@audio/effect'

let p = { rate: 5, depth: 0.5, fs: 44100 }
for (let buf of stream) vibrato(buf, p)

Use when: vocal vibrato, string wobble, instrument simulation Not for: amplitude variation (use tremolo)

Rotary speaker

Leslie cabinet simulation — a treble horn and bass drum spin at independent, inertia-limited rates below a crossover split, each producing Doppler pitch modulation and directivity amplitude modulation as they turn past two virtual mics. Mono in, stereo out.

hornSpeed/drumSpeed rotor rates in Hz (default 0.8/0.7 chorale · 6.7/5.9 tremolo · 0/0 off) · crossover horn/drum split in Hz (default 800) · depth modulation intensity 0–1 (default 1) · hornInertia/drumInertia spin-up/down time constants in seconds (default 0.6/2.5 — the heavier drum lags the horn) · micSpread angle between the two virtual mics in radians (default π/2) · mix wet/dry 0–1 (default 1) · fs sample rate

import { rotary } from '@audio/effect'

// mono in, stereo out: pre-fill both channels with the same dry signal
let left = Float64Array.from(mono), right = Float64Array.from(mono)
let p = { hornSpeed: 6.7, drumSpeed: 5.9, fs: 44100 }
rotary(left, right, p)   // left, right now hold the two virtual-mic outputs

Switching hornSpeed/drumSpeed mid-stream glides through the inertia model instead of snapping — the classic chorale↔tremolo swell.

Use when: organ/guitar Leslie emulation, spinning-speaker swells Not for: plain stereo chorus (use chorus) or static stereo widening (use @audio/spatial)

Ring mod

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'

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

Frequency shifter

Single-sideband frequency shift via Hilbert transform. Every frequency moves by a constant offset (unlike ring mod, which produces sum/difference pairs; unlike pitch shifter, which preserves harmonic ratios). Breaks harmonic relationships → inharmonic, metallic, clangorous.

shift shift in Hz (default 100 · positive = up, negative = down) · mix wet/dry 0–1 (default 1) · taps Hilbert FIR length, must be odd (default 65) · fs sample rate

import { frequencyShifter } from '@audio/effect'

let p = { shift: 200, fs: 44100 }
for (let buf of stream) frequencyShifter(buf, p)

Use when: clangorous barber-pole tones, Bode-style modulation, Moog-style frequency shifting Not for: musical transposition (use pitch shifter or the @audio/shift package)

Pitch shifter

Moved to @audio/shift — 15 algorithms from granular to phase-vocoder to PSOLA:

import { granular } from '@audio/shift'

let out = granular(buf, { ratio: 1.5 })

Auto-wah

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'

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')

Dynamics

Dynamics processing lives in @audio/dynamics — compressor, limiter, gate, expander, deesser, ducker, softclip, compand, multiband, character models (fet/opto/vca/varimu), leveler. See its README for the accurate API (note: dynamics kernels read sampleRate, not fs, and attack/release are in ms).

Delay

Time-based echo and reverberation effects.

Delay

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'

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)

Multitap

Multiple independent delay taps at different times with individual gains.

taps array of { time, gain } objects · fs sample rate

import { multitap } from '@audio/effect'

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)

Ping-pong

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'

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

Reverb

Promoted to @audio/reverb — Schroeder, Freeverb, Dattorro, convolution, FDN, spring, shimmer:

import { freeverb } from '@audio/reverb'

let out = freeverb(buf, { decay: 0.84, damping: 0.5, mix: 0.3, fs: 44100 })

Distortion

Non-linear waveshaping effects.

Distortion / saturation

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'

// 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)

Exciter

Aphex-style aural exciter. Extracts the high band via SVF highpass, runs it through tanh saturation to synthesize harmonics, then mixes the harmonic residue back into the dry signal. Adds perceived "air" and "presence" without EQ boost.

freq highpass cutoff Hz (default 3000) · drive saturation amount 0–1 (default 0.5, maps to 1–10× gain) · amount mix-in level 0–1 (default 0.5) · fs sample rate

import { exciter } from '@audio/effect'

let p = { freq: 4000, drive: 0.6, amount: 0.4, fs: 44100 }
for (let buf of stream) exciter(buf, p)

Use when: dull vocals, lifeless cymbals, mastering polish, restoring high-end after compression Not for: spectral shaping (use a shelf/EQ from @audio/filter) — exciter adds harmonics, not gain

Bitcrusher

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'

// 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)

Spatial

Stereo image and positioning effects. All take (left, right, params) and return [left, right].

Stereo widener

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/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)

Haas effect

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/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)

Panner

Constant-power stereo panning using cos/sin law.

pan −1 = full left, 0 = center, +1 = full right (default 0)

import { panner } from '@audio/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

Auto-panner

LFO-driven constant-power pan — signal sweeps between speakers periodically.

rate LFO rate in Hz (default 0.5) · depth sweep depth 0–1 (default 1, full excursion) · fs sample rate

import { autoPanner } from '@audio/spatial'

let p = { rate: 0.5, depth: 1, fs: 44100 }
for (let [L, R] of stereoStream) autoPanner(L, R, p)

Use when: rhythmic stereo motion, ambient spatialization, auto-panning leads Not for: static placement (use panner)

Utility

Signal conditioning and mixing tools.

Gain

Simple level adjustment in decibels.

dB gain in dB (default 0)

import { gain } from '@audio/effect'

for (let buf of stream) gain(buf, { dB: -6 })

Mixer

Sums an array of buffers with individual gain multipliers.

channels array of { buffer, gain } objects

import { mixer } from '@audio/effect'

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

Slew limiter

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'

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

Noise shaping

Error-feedback quantization — shapes quantization noise out of the audible band.

bits target bit depth (default 16)

import { noiseShaping } from '@audio/effect'

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)

Tape stop

Variable-rate playback with a decelerating (or accelerating) read pointer — turntable power-off / tape-deck stop, and the reverse spin-up. Whole-buffer effect: needs the full signal in one call, not a per-block stream.

at when the stop/start begins, in seconds (default 0) · time ramp duration in seconds (default 1) · curve speed-profile exponent — 1 = physical constant-torque linear decay, >1 = faster initial drop, <1 = held then dropping (default 1) · direction 'stop' or 'start' (default 'stop') · flutter 0–1 random rate wobble during the ramp (default 0)

import { tapeStop } from '@audio/effect'

tapeStop(buf, { at: 2, time: 1.5, direction: 'stop', fs: 44100 })

Use when: DJ/turntable power-off, tape-deck stop/start, transition sweeps Not for: continuous pitch modulation (use vibrato) or tempo-locked time-stretch