reaper-jsfx-audio
SKILL.md
REAPER JSFX Audio Effects
DSP algorithms and patterns for audio effects in JSFX. Covers filters, dynamics processors, delays, reverbs, and modulation effects.
Requires: reaper-jsfx-core for language fundamentals.
Rules
| Rule | Description |
|---|---|
| filters | Biquad, SVF, ZDF, one-pole filters with coefficient calculation |
| dynamics | Compressor, limiter, gate, expander, envelope detection |
| delays | Delay lines, circular buffers, chorus, flanger, comb filters |
| reverb | Algorithmic reverb, allpass networks, FDN, early reflections |
| distortion | Waveshaping, soft/hard clipping, saturation, tube emulation |
| modulation | LFO patterns, tremolo, vibrato, phaser, ring modulation |
Official Documentation
External References
- Audio EQ Cookbook - Biquad filter coefficients
- Tale's JSFX Libraries - Reference implementations
- musicdsp.org - DSP algorithms and code
Key Principles
1. Coefficient Calculation in @slider
Always calculate filter coefficients when parameters change, not per-sample:
@slider
omega = 2 * $pi * cutoff / srate;
sin_omega = sin(omega);
cos_omega = cos(omega);
alpha = sin_omega / (2 * q);
// Lowpass coefficients (RBJ cookbook)
a0 = 1 + alpha;
b0 = ((1 - cos_omega) / 2) / a0;
b1 = (1 - cos_omega) / a0;
b2 = b0;
a1 = (-2 * cos_omega) / a0;
a2 = (1 - alpha) / a0;
@sample
// Only apply coefficients here
out = b0*in + b1*z1 + b2*z2 - a1*z1_out - a2*z2_out;
2. State Variable Preservation
Filter and delay states must persist between samples:
@init
// Initialize filter states to zero
z1 = z2 = 0;
z1_out = z2_out = 0;
@sample
// Update states after processing
z2 = z1;
z1 = input;
z2_out = z1_out;
z1_out = output;
3. Gain Staging
Maintain proper gain throughout the signal chain:
@init
// Keep track of gain changes
input_gain = 1;
output_gain = 1;
@slider
// Convert dB to linear
input_gain = 10^(input_db / 20);
output_gain = 10^(output_db / 20);
@sample
// Apply input gain
sample = spl0 * input_gain;
// Process
processed = do_something(sample);
// Apply output gain and makeup
spl0 = processed * output_gain;
4. Oversampling for Nonlinear Processing
Distortion and saturation benefit from oversampling to reduce aliasing:
@init
oversample = 2; // 2x oversampling
@sample
// Upsample (simple interpolation)
s1 = spl0;
s2 = (spl0 + last_input) * 0.5;
last_input = spl0;
// Process at higher rate
s1 = saturate(s1);
s2 = saturate(s2);
// Downsample (simple averaging)
spl0 = (s1 + s2) * 0.5;
Quick Reference
| Use Case | Rule |
|---|---|
| EQ / Filter | filters |
| Compressor / Limiter | dynamics |
| Delay / Echo | delays |
| Reverb | reverb |
| Distortion / Saturation | distortion |
| Chorus / Flanger / Phaser | modulation |
Common Effect Patterns
Stereo Processing
@sample
// Process left and right identically
spl0 = process(spl0);
spl1 = process(spl1);
// Or use mid-side
mid = (spl0 + spl1) * 0.5;
side = (spl0 - spl1) * 0.5;
mid = process_mid(mid);
side = process_side(side);
spl0 = mid + side;
spl1 = mid - side;
Dry/Wet Mix
@slider
dry = 1 - wet_amount;
wet = wet_amount;
@sample
dry_signal = spl0;
wet_signal = process(spl0);
spl0 = dry_signal * dry + wet_signal * wet;
Bypass with Smoothing
@slider
bypass_target = bypass ? 0 : 1;
@sample
// Smooth bypass transition
bypass_smooth += 0.001 * (bypass_target - bypass_smooth);
dry_signal = spl0;
wet_signal = process(spl0);
spl0 = dry_signal * (1 - bypass_smooth) + wet_signal * bypass_smooth;
Weekly Installs
2
Repository
mthines/jsfx-ag…t-skillsFirst Seen
12 days ago
Security Audits
Installed on
amp2
cline2
opencode2
cursor2
kimi-cli2
codex2