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 TypeWhat It DoesUse Case
Low-passLets low frequencies throughRemove hiss, muffle sound
High-passLets high frequencies throughRemove rumble, thin sound
Band-passLets a range throughIsolate frequencies
NotchCuts a narrow rangeRemove feedback
Peaking EQBoosts/cuts a rangeTone 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.