Please bookmark this page to avoid losing your image tool!

Audio URL Voice Changer With All Effects

(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.
async function processImage(originalImg, audioUrl = 'https://upload.wikimedia.org/wikipedia/commons/4/4d/Human-voice.ogg', effect = 'chipmunk') {
    // 1. Create the container and UI elements
    const container = document.createElement('div');
    container.style.border = "1px solid #ccc";
    container.style.borderRadius = "8px";
    container.style.padding = "20px";
    container.style.textAlign = "center";
    container.style.fontFamily = "sans-serif";
    container.style.maxWidth = "400px";
    container.style.margin = "auto";
    container.style.backgroundColor = "#f9f9f9";

    // Add the image which acts as a visual element, like an album cover.
    originalImg.style.maxWidth = '100%';
    originalImg.style.maxHeight = '250px';
    originalImg.style.objectFit = 'contain';
    originalImg.style.marginBottom = '15px';
    originalImg.style.borderRadius = '5px';
    container.appendChild(originalImg);
    
    // Add UI components for status and controls
    const statusEl = document.createElement('p');
    statusEl.textContent = 'Initializing...';
    statusEl.style.minHeight = '1.2em';
    statusEl.style.color = '#555';
    container.appendChild(statusEl);

    const controlsDiv = document.createElement('div');
    const playBtn = document.createElement('button');
    playBtn.textContent = '▶ Play';
    playBtn.disabled = true;
    playBtn.style.cssText = 'padding: 10px 20px; margin: 5px; cursor: pointer; border: 1px solid #ddd; background-color: #f0f0f0; border-radius: 5px; font-size: 16px;';
    
    const stopBtn = document.createElement('button');
    stopBtn.textContent = '■ Stop';
    stopBtn.disabled = true;
    stopBtn.style.cssText = 'padding: 10px 20px; margin: 5px; cursor: pointer; border: 1px solid #ddd; background-color: #f0f0f0; border-radius: 5px; font-size: 16px;';


    controlsDiv.appendChild(playBtn);
    controlsDiv.appendChild(stopBtn);
    container.appendChild(controlsDiv);

    // 2. Web Audio API setup
    if (!audioUrl) {
        statusEl.textContent = 'Error: No audio URL provided.';
        return container;
    }

    let audioContext;
    let audioBuffer;
    let sourceNode = null;
    
    try {
        window.AudioContext = window.AudioContext || window.webkitAudioContext;
        audioContext = new AudioContext();
    } catch (e) {
        statusEl.textContent = 'Error: Web Audio API is not supported in this browser.';
        return container;
    }

    // --- Helper functions for generating effect data ---
    const makeDistortionCurve = (amount = 50) => {
        const k = amount;
        const n_samples = 44100;
        const curve = new Float32Array(n_samples);
        const deg = Math.PI / 180;
        for (let i = 0; i < n_samples; ++i) {
            const x = i * 2 / n_samples - 1;
            curve[i] = (3 + k) * x * 20 * deg / (Math.PI + k * Math.abs(x));
        }
        return curve;
    };

    const createReverbImpulse = () => {
        const sampleRate = audioContext.sampleRate;
        const duration = 2; // seconds
        const decay = 2;
        const length = sampleRate * duration;
        const impulse = audioContext.createBuffer(2, length, sampleRate);
        const impulseL = impulse.getChannelData(0);
        const impulseR = impulse.getChannelData(1);
        for (let i = 0; i < length; i++) {
            const n = length - i;
            impulseL[i] = (Math.random() * 2 - 1) * Math.pow(n / length, decay);
            impulseR[i] = (Math.random() * 2 - 1) * Math.pow(n / length, decay);
        }
        return impulse;
    };

    // --- Audio loading ---
    const loadAudio = async () => {
        try {
            statusEl.textContent = `Loading audio...`;
            const response = await fetch(audioUrl, { mode: 'cors' });
            if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
            const arrayBuffer = await response.arrayBuffer();
            audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
            statusEl.textContent = `Ready to play with "${effect}" effect.`;
            playBtn.disabled = false;
        } catch (error) {
            console.error('Error loading audio:', error);
            statusEl.textContent = `Error loading audio. Check URL and CORS.`;
        }
    };
    
    loadAudio();

    // --- Playback logic ---
    const play = () => {
        if (!audioBuffer) return;
        if (sourceNode) sourceNode.stop();
        
        if (audioContext.state === 'suspended') audioContext.resume();

        sourceNode = audioContext.createBufferSource();
        sourceNode.buffer = audioBuffer;

        let currentNode = sourceNode;
        const effectToApply = (typeof effect === 'string') ? effect.toLowerCase() : 'none';

        switch (effectToApply) {
            case 'chipmunk':
                sourceNode.playbackRate.value = 1.6;
                break;
            case 'robot':
                sourceNode.playbackRate.value = 0.7;
                break;
            case 'monster': {
                sourceNode.playbackRate.value = 0.6;
                const distortion = audioContext.createWaveShaper();
                distortion.curve = makeDistortionCurve(100);
                distortion.oversample = '4x';
                currentNode.connect(distortion);
                currentNode = distortion;
                break;
            }
            case 'phone': {
                const lowpass = audioContext.createBiquadFilter();
                lowpass.type = "lowpass";
                lowpass.frequency.setValueAtTime(2000, audioContext.currentTime);

                const highpass = audioContext.createBiquadFilter();
                highpass.type = "highpass";
                highpass.frequency.setValueAtTime(500, audioContext.currentTime);
                
                currentNode.connect(highpass);
                highpass.connect(lowpass);
                currentNode = lowpass;
                break;
            }
            case 'reverb': {
                const convolver = audioContext.createConvolver();
                convolver.buffer = createReverbImpulse();
                const dryGain = audioContext.createGain();
                dryGain.gain.value = 0.7;
                const wetGain = audioContext.createGain();
                wetGain.gain.value = 0.3;

                currentNode.connect(dryGain);
                dryGain.connect(audioContext.destination);
                currentNode.connect(convolver);
                convolver.connect(wetGain);
                wetGain.connect(audioContext.destination);

                startPlayback();
                return;
            }
            case 'echo': {
                const delay = audioContext.createDelay(5.0);
                delay.delayTime.value = 0.4;
                const feedback = audioContext.createGain();
                feedback.gain.value = 0.5;

                currentNode.connect(audioContext.destination); // Dry path
                
                currentNode.connect(delay); // Wet path
                delay.connect(feedback);
                feedback.connect(delay); // Feedback loop
                delay.connect(audioContext.destination);

                startPlayback();
                return;
            }
            case 'none':
            default:
                break;
        }

        currentNode.connect(audioContext.destination);
        startPlayback();
    };
    
    const startPlayback = () => {
         sourceNode.onended = () => {
            stopBtn.disabled = true;
            playBtn.disabled = false;
            sourceNode = null;
        };
        sourceNode.start(0);
        stopBtn.disabled = false;
        playBtn.disabled = true;
    };

    const stop = () => {
        if (sourceNode) {
            sourceNode.stop(0); // onended will fire and reset the UI state
        }
    };
    
    playBtn.addEventListener('click', play);
    stopBtn.addEventListener('click', stop);

    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 URL Voice Changer With All Effects is an online tool that allows users to modify audio files using various effects. It supports effects like ‘chipmunk’, ‘robot’, ‘monster’, ‘phone’, ‘reverb’, and ‘echo’, enabling creative alterations to voice recordings or sounds. Users can input an audio URL to play the audio with their selected effect, making it useful for content creators, podcasters, or anyone looking to add unique audio features to their projects. The tool is intuitive and provides a simple interface for playing and stopping audio playback, allowing for easy user interaction.

Leave a Reply

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