Please bookmark this page to avoid losing your image tool!

Audio Filter Tool

(Free & Supports Bulk Upload)

Drag & drop your images here or

The result will appear here...
You can edit the below JavaScript code to customize the image tool.
function processImage(originalImg, filterType = 'lowpass', defaultFreq = 1000) {
    const freqValue = Number(defaultFreq) || 1000;
    const validFilters = ['lowpass', 'highpass', 'bandpass', 'lowshelf', 'highshelf', 'peaking', 'notch', 'allpass'];
    const fType = validFilters.includes(filterType) ? filterType : 'lowpass';

    const container = document.createElement('div');
    container.style.position = 'relative';
    container.style.display = 'inline-block';
    container.style.fontFamily = 'Arial, sans-serif';
    
    const cWidth = Math.max(originalImg.width, 320); 
    const cHeight = Math.max(originalImg.height, 420);
    
    container.style.width = cWidth + 'px';
    container.style.maxWidth = '100%';
    container.style.boxShadow = '0px 4px 15px rgba(0,0,0,0.5)';
    container.style.borderRadius = '8px';
    container.style.overflow = 'hidden';

    // Set up visualizer canvas
    const canvas = document.createElement('canvas');
    canvas.width = cWidth;
    canvas.height = cHeight;
    canvas.style.display = 'block';
    canvas.style.width = '100%';
    canvas.style.height = 'auto';
    container.appendChild(canvas);

    const ctx = canvas.getContext('2d');
    
    // Calculate best fit logic for cover art (original image)
    const imgRatio = originalImg.width / originalImg.height;
    const cRatio = cWidth / cHeight;
    let drawW = cWidth;
    let drawH = cHeight;
    let drawX = 0;
    let drawY = 0;
    
    if (imgRatio > cRatio) {
        drawH = cWidth / imgRatio;
        drawY = (cHeight - drawH) / 2;
    } else {
        drawW = cHeight * imgRatio;
        drawX = (cWidth - drawW) / 2;
    }

    function renderBaseImage() {
        ctx.fillStyle = '#111';
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(originalImg, drawX, drawY, drawW, drawH);
    }
    
    // Initial Render
    renderBaseImage();

    // UI Controls Frame
    const controls = document.createElement('div');
    controls.style.position = 'absolute';
    controls.style.bottom = '10px';
    controls.style.left = '10px';
    controls.style.width = 'calc(100% - 20px)';
    controls.style.boxSizing = 'border-box';
    controls.style.background = 'rgba(20, 20, 20, 0.85)';
    controls.style.padding = '15px';
    controls.style.borderRadius = '8px';
    controls.style.color = '#fff';
    controls.style.display = 'flex';
    controls.style.flexDirection = 'column';
    controls.style.gap = '12px';
    controls.style.zIndex = '10';
    container.appendChild(controls);

    // Title
    const title = document.createElement('div');
    title.innerText = 'Audio Filter Tool';
    title.style.fontWeight = 'bold';
    title.style.fontSize = '16px';
    title.style.textAlign = 'center';
    title.style.marginBottom = '5px';
    controls.appendChild(title);

    // Audio Input
    const row1 = document.createElement('div');
    row1.style.display = 'flex';
    row1.style.justifyContent = 'space-between';
    row1.style.alignItems = 'center';

    const lblSrc = document.createElement('span');
    lblSrc.innerText = 'Audio Source:';
    lblSrc.style.fontSize = '14px';
    row1.appendChild(lblSrc);

    const fileIn = document.createElement('input');
    fileIn.type = 'file';
    fileIn.accept = 'audio/*';
    fileIn.style.width = '160px';
    fileIn.style.fontSize = '12px';
    row1.appendChild(fileIn);
    controls.appendChild(row1);

    // Filter Type Selector
    const row2 = document.createElement('div');
    row2.style.display = 'flex';
    row2.style.justifyContent = 'space-between';
    row2.style.alignItems = 'center';

    const lblType = document.createElement('span');
    lblType.innerText = 'Filter Type:';
    lblType.style.fontSize = '14px';
    row2.appendChild(lblType);

    const selType = document.createElement('select');
    selType.style.width = '120px';
    validFilters.forEach(f => {
        const op = document.createElement('option');
        op.value = f;
        op.innerText = f;
        if(f === fType) op.selected = true;
        selType.appendChild(op);
    });
    row2.appendChild(selType);
    controls.appendChild(row2);

    // Frequency Slider
    const row3 = document.createElement('div');
    row3.style.display = 'flex';
    row3.style.justifyContent = 'space-between';
    row3.style.alignItems = 'center';

    const lblFreq = document.createElement('span');
    lblFreq.innerText = `Freq (${freqValue}Hz):`;
    lblFreq.style.fontSize = '14px';
    row3.appendChild(lblFreq);

    const rngFreq = document.createElement('input');
    rngFreq.type = 'range';
    rngFreq.min = '20';
    rngFreq.max = '20000';
    rngFreq.value = freqValue;
    rngFreq.style.width = '120px';
    row3.appendChild(rngFreq);
    controls.appendChild(row3);

    // Resonance Slider (Q)
    const row4 = document.createElement('div');
    row4.style.display = 'flex';
    row4.style.justifyContent = 'space-between';
    row4.style.alignItems = 'center';

    const lblQ = document.createElement('span');
    lblQ.innerText = `Q (Resonance):`;
    lblQ.style.fontSize = '14px';
    row4.appendChild(lblQ);

    const rngQ = document.createElement('input');
    rngQ.type = 'range';
    rngQ.min = '0';
    rngQ.max = '30';
    rngQ.step = '0.5';
    rngQ.value = '5';
    rngQ.style.width = '120px';
    row4.appendChild(rngQ);
    controls.appendChild(row4);

    // Play/Pause Button
    const playBtn = document.createElement('button');
    playBtn.innerText = 'Play Synth Drone';
    playBtn.style.padding = '10px';
    playBtn.style.background = '#4CAF50';
    playBtn.style.color = '#fff';
    playBtn.style.border = 'none';
    playBtn.style.borderRadius = '5px';
    playBtn.style.cursor = 'pointer';
    playBtn.style.fontWeight = 'bold';
    playBtn.style.fontSize = '14px';
    controls.appendChild(playBtn);

    // Web Audio API Elements
    let audioCtx;
    let source;
    let filter;
    let analyser;
    let dataArray;
    let bufferLength;
    let isPlaying = false;
    let audioBuffer = null;

    // Drawing visually responsive spectrum
    function drawVisualizer() {
        if (!isPlaying) return;
        requestAnimationFrame(drawVisualizer);

        analyser.getByteFrequencyData(dataArray);

        renderBaseImage();
        ctx.fillStyle = 'rgba(0, 0, 0, 0.45)';
        ctx.fillRect(0, 0, canvas.width, canvas.height);

        const ctrlHeight = controls.offsetHeight;
        const maxBarY = canvas.height - ctrlHeight - 15;
        const maxBarH = canvas.height * 0.55; 
        
        const barWidth = (canvas.width / bufferLength) * 2;
        let x = 0;

        for (let i = 0; i < bufferLength; i++) {
            const barHeight = (dataArray[i] / 255) * maxBarH;

            const r = barHeight + (25 * (i / bufferLength));
            const g = 250 * (i / bufferLength);
            const b = 150;

            ctx.fillStyle = `rgb(${r},${g},${b})`;
            ctx.fillRect(x, maxBarY - barHeight, barWidth, barHeight);

            x += barWidth + 1;
        }
    }

    // Connect interactions
    fileIn.addEventListener('change', (e) => {
        const file = e.target.files[0];
        if(!file) return;
        const reader = new FileReader();
        reader.onload = (evt) => {
            const arrayBuffer = evt.target.result;
            if(!audioCtx) audioCtx = new (window.AudioContext || window.webkitAudioContext)();
            audioCtx.decodeAudioData(arrayBuffer, (buffer) => {
                audioBuffer = buffer;
                if(source) {
                    try { source.stop(); } catch(err) {}
                    source = null;
                }
                if(isPlaying) playBtn.click(); 
                playBtn.innerText = 'Play Uploaded Audio';
            });
        };
        reader.readAsArrayBuffer(file);
    });

    rngFreq.addEventListener('input', (e) => {
        lblFreq.innerText = `Freq (${e.target.value}Hz):`;
        if (filter && audioCtx) filter.frequency.setValueAtTime(e.target.value, audioCtx.currentTime);
    });

    rngQ.addEventListener('input', (e) => {
        if (filter && audioCtx) filter.Q.setValueAtTime(e.target.value, audioCtx.currentTime);
    });

    selType.addEventListener('change', (e) => {
        if (filter) filter.type = e.target.value;
    });

    playBtn.addEventListener('click', () => {
        if (!audioCtx) audioCtx = new (window.AudioContext || window.webkitAudioContext)();

        if (isPlaying) {
            if (audioCtx.state === 'running') audioCtx.suspend();
            playBtn.innerText = audioBuffer ? 'Play Uploaded Audio' : 'Play Synth Drone';
            playBtn.style.background = '#4CAF50';
            isPlaying = false;
            setTimeout(renderBaseImage, 50); // Restore raw image display
        } else {
            if (!source) {
                if (audioCtx.state === 'suspended') audioCtx.resume();

                filter = audioCtx.createBiquadFilter();
                filter.type = selType.value;
                filter.frequency.setValueAtTime(rngFreq.value, audioCtx.currentTime);
                filter.Q.setValueAtTime(rngQ.value, audioCtx.currentTime);

                analyser = audioCtx.createAnalyser();
                analyser.fftSize = 256;
                bufferLength = analyser.frequencyBinCount;
                dataArray = new Uint8Array(bufferLength);

                if (audioBuffer) { // User Audio
                    source = audioCtx.createBufferSource();
                    source.buffer = audioBuffer;
                    source.loop = true;
                } else { // Synthesized Tone (Sawtooth at C3)
                    source = audioCtx.createOscillator();
                    source.type = 'sawtooth';
                    source.frequency.setValueAtTime(130.81, audioCtx.currentTime); 
                }

                source.connect(filter);
                filter.connect(analyser);

                const gainNode = audioCtx.createGain();
                gainNode.gain.setValueAtTime(0.6, audioCtx.currentTime); // Prevent blasting volume

                analyser.connect(gainNode);
                gainNode.connect(audioCtx.destination);

                source.start(0);
            } else {
                if (audioCtx.state === 'suspended') audioCtx.resume();
            }

            playBtn.innerText = 'Pause Filter';
            playBtn.style.background = '#f44336';
            isPlaying = true;
            drawVisualizer();
        }
    });

    return container;
}

Free Image Tool Creator

Can't find the image tool you're looking for?
Create one based on your own needs now!

Description

The Audio Filter Tool is an interactive utility that allows users to experiment with various audio frequency filters while visualizing the sound waves over an image. Users can upload their own audio files or use a synthesized drone to test different filter types, including lowpass, highpass, bandpass, notch, and more. The tool provides real-time control over frequency and resonance (Q factor), accompanied by a dynamic visualizer that maps audio frequencies to a visual spectrum overlaid on a selected image. This tool is ideal for musicians, sound designers, or students looking to understand audio signal processing and filter characteristics through visual and auditory feedback.

Leave a Reply

Your email address will not be published. Required fields are marked *