(function() { var onDOMContentLoaded = function() { window.AudioContext = window.AudioContext || window.webkitAudioContext; try { // Create the instance of AudioContext var context = new AudioContext(); } catch (error) { window.alert(error.message + ' : Please use Chrome or Safari.'); return; } // for createObjectURL window.URL = window.URL || window.webkitURL; // for HTMLAudioElement var audio = null; // for legacy browsers context.createGain = context.createGain || context.createGainNode; // Create the instance of GainNode var gain = context.createGain(); // Create the instance of BiquadFilterNode var filter = context.createBiquadFilter(); // for playback rate (HTMLAudioElement) var playbackRate = document.getElementById('range-playback-rate').valueAsNumber; // Start / Pause Button var controlButton = document.getElementById('button-control-audio'); // for drawing sound wave (spectrum) // Create the instance of AnalyserNode var analyser = context.createAnalyser(); analyser.minDecibels = -100; analyser.maxDecibels = 0; var canvas = document.querySelector('canvas'); var canvasContext = canvas.getContext('2d'); var timerid = null; // Frequency resolution var fsDivN = context.sampleRate / analyser.fftSize; // This value is the number of samples during 500 Hz var n500Hz = Math.floor(500 / fsDivN); var drawWave = function() { var width = canvas.width; var height = canvas.height; var paddingTop = 20; var paddingBottom = 20; var paddingLeft = 30; var paddingRight = 30; var innerWidth = width - paddingLeft - paddingRight; var innerHeight = height - paddingTop - paddingBottom; var innerBottom = height - paddingBottom; var range = analyser.maxDecibels - analyser.minDecibels; // 70 dB // Get data for drawing spectrum (dB) var spectrums = new Float32Array(analyser.frequencyBinCount / 4); analyser.getFloatFrequencyData(spectrums); // Clear previous data canvasContext.clearRect(0, 0, width, height); // Draw spectrum (dB) canvasContext.beginPath(); for (var i = 0, len = spectrums.length; i < len; i++) { var x = Math.floor((i / len) * innerWidth) + paddingLeft; var y = Math.floor(-1 * ((spectrums[i] - analyser.maxDecibels) / range) * innerHeight) + paddingTop; if (i === 0) { canvasContext.moveTo(x, y); } else { canvasContext.lineTo(x, y); } if (i % n500Hz === 0) { var text = (500 * (i / n500Hz)) + ' Hz'; // index -> frequency // Draw grid (X) canvasContext.fillStyle = 'rgba(255, 0, 0, 1.0)'; canvasContext.fillRect(x, paddingTop, 1, innerHeight); // Draw text (X) canvasContext.fillStyle = 'rgba(255, 255, 255, 1.0)'; canvasContext.font = '12px "Times New Roman"'; canvasContext.fillText(text, (x - (canvasContext.measureText(text).width / 2)), (height - 3)); } } canvasContext.strokeStyle = 'rgba(0, 0, 255, 1.0)'; canvasContext.lineWidth = 2; canvasContext.lineCap = 'round'; canvasContext.lineJoin = 'miter'; canvasContext.stroke(); // Draw grid and text (Y) for (var i = analyser.minDecibels; i <= analyser.maxDecibels; i += 10) { var gy = Math.floor(-1 * ((i - analyser.maxDecibels) / range) * innerHeight) + paddingTop; // Draw grid (Y) canvasContext.fillStyle = 'rgba(255, 0, 0, 1.0)'; canvasContext.fillRect(paddingLeft, gy, innerWidth, 1); // Draw text (Y) canvasContext.fillStyle = 'rgba(255, 255, 255, 1.0)'; canvasContext.font = '12px "Times New Roman"'; canvasContext.fillText((i + ' dB'), 3, gy); } timerid = window.setTimeout(drawWave, 20); }; var setupAudio = function(src) { // Clear previous audio if (audio instanceof HTMLAudioElement) { audio.pause(); audio = null; controlButton.innerHTML = '<span class="icon-start"></span>'; } // Create the instance of HTMLAudioElement audio = new Audio(src); audio.setAttribute('controls', true); // Create the instance of MediaElementAudioSourceNode after "onloadstart" event audio.addEventListener('loadstart', function(event) { window.alert('Start "' + event.type + '" !!'); // Create the instance of MediaElementAudioSourceNode var source = context.createMediaElementSource(audio); // MediaElementAudioSourceNode (Input) -> BiquadFilterNode (Filter) -> GainNode (Volume) -> AnalyserNode (Visualization) -> AudioDestinationNode (Output) source.connect(filter) filter.connect(gain); gain.connect(analyser); analyser.connect(context.destination); }, false); audio.addEventListener('play', function() { drawWave(); controlButton.innerHTML = '<span class="icon-pause"></span>'; }, false); audio.addEventListener('pause', function() { if (timerid !== null) { window.clearTimeout(timerid); timerid = null; } controlButton.innerHTML = '<span class="icon-start"></span>'; }, false); }; /* * Event Listener */ // File Uploader document.querySelector('[type="file"] + button').addEventListener(EventWrapper.CLICK, function() { document.querySelector('[type="file"]').click(); }, false); document.querySelector('[type="file"]').addEventListener('change', function(event) { var uploader = this; var progressArea = document.getElementById('progress-file-upload-audio'); // Get the instance of File (extends Blob) var file = event.target.files[0]; if (!(file instanceof File)) { window.alert('Please upload file.'); } else if (file.type.indexOf('audio') === -1) { window.alert('Please upload audio file.'); } else { setupAudio(window.URL.createObjectURL(file)); } }, false); // Start or Pause audio controlButton.addEventListener(EventWrapper.CLICK, function() { if (audio instanceof HTMLAudioElement) { if (audio.paused) { audio.playbackRate = playbackRate; audio.play(); } else { audio.pause(); } } }, false); // Control Volume document.getElementById('range-volume').addEventListener('input', function() { var min = gain.gain.minValue || 0; var max = gain.gain.maxValue || 1; if ((this.valueAsNumber >= min) && (this.valueAsNumber <= max)) { gain.gain.value = this.valueAsNumber; document.getElementById('output-volume').textContent = this.value; } }, false); // Control playBackRate document.getElementById('range-playback-rate').addEventListener('input', function() { if (audio instanceof HTMLAudioElement) { audio.playbackRate = playbackRate = this.valueAsNumber; } else { playbackRate = this.valueAsNumber; } document.getElementById('output-playback-rate').textContent = this.value; }, false); // Select type document.getElementById('select-filter').addEventListener('change', function() { filter.type = (typeof filter.type === 'string') ? this.value : this.selectedIndex; }, false); // Control frequency document.getElementById('range-frequency').addEventListener('input', function() { var min = filter.frequency.minValue || 10; var max = filter.frequency.maxValue || (context.sampleRate / 2); if ((this.valueAsNumber >= min) && (this.valueAsNumber <= max)) { filter.frequency.value = this.valueAsNumber; document.getElementById('output-frequency').textContent = this.value; } }, false); // Control detune document.getElementById('range-detune').addEventListener('input', function() { var min = filter.detune.minValue || -4800; var max = filter.detune.maxValue || 4800; if ((this.valueAsNumber >= min) && (this.valueAsNumber <= max)) { filter.detune.value = this.valueAsNumber; document.getElementById('output-detune').textContent = this.value; } }, false); // Control Q document.getElementById('range-Q').addEventListener('input', function() { var min = filter.Q.minValue || 0.0001; var max = filter.Q.maxValue || 1000; if ((this.valueAsNumber >= min) && (this.valueAsNumber <= max)) { filter.Q.value = this.valueAsNumber; document.getElementById('output-Q').textContent = this.value; } }, false); // Control gain document.getElementById('range-filter-gain').addEventListener('input', function() { var min = filter.gain.minValue || -40; var max = filter.gain.maxValue || 40; if ((this.valueAsNumber >= min) && (this.valueAsNumber <= max)) { filter.gain.value = this.valueAsNumber; document.getElementById('output-filter-gain').textContent = this.value; } }, false); }; if ((document.readyState === 'interactive') || (document.readyState === 'complete')) { onDOMContentLoaded(); } else { document.addEventListener('DOMContentLoaded', onDOMContentLoaded, true); } })();
function EventWrapper(){ } (function(){ var click = ''; var start = ''; var move = ''; var end = ''; // Touch Panel ? if (/iPhone|iPad|iPod|Android/.test(navigator.userAgent)) { click = 'click'; start = 'touchstart'; move = 'touchmove'; end = 'touchend'; } else { click = 'click'; start = 'mousedown'; move = 'mousemove'; end = 'mouseup'; } EventWrapper.CLICK = click; EventWrapper.START = start; EventWrapper.MOVE = move; EventWrapper.END = end; })();