Chapter 18
Filters & Effects
Learning Objectives
- Understand audio filters
- Learn about common effects
- Implement filters in code
- See how MixMind uses filters
Audio Filters
Filters modify the frequency content of audio. They can boost or cut specific frequency ranges.
| Filter Type | What It Does | Use Case |
|---|---|---|
| Low-pass | Lets low frequencies through | Remove hiss, muffle sound |
| High-pass | Lets high frequencies through | Remove rumble, thin sound |
| Band-pass | Lets a range through | Isolate frequencies |
| Notch | Cuts a narrow range | Remove feedback |
| Peaking EQ | Boosts/cuts a range | Tone shaping |
BiquadFilter
// Create filter
const filter = audioContext.createBiquadFilter();
// Set filter type
filter.type = 'lowpass'; // 'highpass', 'bandpass', 'notch', 'peaking', etc.
// Set parameters
filter.frequency.value = 1000; // Cutoff frequency (Hz)
filter.Q.value = 1; // Resonance (0.0001 to 1000)
filter.gain.value = 0; // Gain in dB (for peaking/shelf)
// Connect
source.connect(filter);
filter.connect(audioContext.destination);
// Filter types:
// 'lowpass', 'highpass', 'bandpass', 'lowshelf', 'highshelf',
// 'peaking', 'notch', 'allpass'
Common Effects
Delay
// Create echo effect
const delay = audioContext.createDelay();
delay.delayTime.value = 0.5; // 500ms
const feedback = audioContext.createGain();
feedback.gain.value = 0.5; // 50% feedback
// Connect: source -> delay -> feedback -> delay (loop)
source.connect(delay);
delay.connect(feedback);
feedback.connect(delay);
delay.connect(audioContext.destination);
Reverb
// Create convolver for reverb
const convolver = audioContext.createConvolver();
// Load impulse response (reverb sound)
const response = await fetch('reverb-impulse.wav');
const arrayBuffer = await response.arrayBuffer();
const impulse = await audioContext.decodeAudioData(arrayBuffer);
convolver.buffer = impulse;
// Connect
source.connect(convolver);
convolver.connect(audioContext.destination);
Distortion
// Create waveshaper for distortion
const distortion = audioContext.createWaveShaper();
// Create distortion curve
function makeDistortionCurve(amount) {
const samples = 44100;
const curve = new Float32Array(samples);
const deg = Math.PI / 180;
for (let i = 0; i < samples; i++) {
const x = (i * 2) / samples - 1;
curve[i] = (3 + amount) * x * 20 * deg / (Math.PI + amount * Math.abs(x));
}
return curve;
}
distortion.curve = makeDistortionCurve(400);
distortion.oversample = '4x';
🎵 MixMind Connection
How MixMind Uses Filters
// EQ transition effect
class EQTransition {
async apply(track1, track2, duration) {
// Fade out bass on track 1
const filter1 = audioContext.createBiquadFilter();
filter1.type = 'lowpass';
filter1.frequency.setValueAtTime(20000, audioContext.currentTime);
filter1.frequency.exponentialRampToValueAtTime(
200,
audioContext.currentTime + duration
);
// Fade in bass on track 2
const filter2 = audioContext.createBiquadFilter();
filter2.type = 'highpass';
filter2.frequency.setValueAtTime(20, audioContext.currentTime);
filter2.frequency.exponentialRampToValueAtTime(
2000,
audioContext.currentTime + duration
);
// Apply filters
// ... connection and mixing code
}
}
// Stem separation uses filters too
class StemSeparator {
// After neural network separation, apply cleanup filters
cleanupStems(stems) {
// Remove artifacts from vocal stem
const vocalFilter = audioContext.createBiquadFilter();
vocalFilter.type = 'highpass';
vocalFilter.frequency.value = 80; // Remove low rumble
// Smooth instrumental
const instFilter = audioContext.createBiquadFilter();
instFilter.type = 'peaking';
instFilter.frequency.value = 3000;
instFilter.gain.value = -3; // Reduce harshness
}
}
Exercise 18.1: Practice
Goal: Apply what you've learned in this chapter
Try the concepts from this chapter in your browser's console or a simple HTML file. Experiment with the code examples and modify them to see what happens.
📝 Quick Reference:
Review the key concepts from this chapter and make sure you understand each one before moving to the next chapter.