local_audio_visualizer.js | |
---|---|
window.onload = function() {
var element = document.getElementById('container')
dropAndLoad(element, init, "ArrayBuffer")
} | |
Reusable dropAndLoad function: it reads a local file dropped on a
| function dropAndLoad(dropElement, callback, readFormat) {
var readFormat = readFormat || "DataUrl"
dropElement.addEventListener('dragover', function(e) {
e.stopPropagation()
e.preventDefault()
e.dataTransfer.dropEffect = 'copy'
}, false)
dropElement.addEventListener('drop', function(e) {
e.stopPropagation()
e.preventDefault()
loadFile(e.dataTransfer.files[0])
}, false)
function loadFile(files) {
var file = files
var reader = new FileReader()
reader.onload = function(e) {
callback(e.target.result)
}
reader['readAs'+readFormat](file)
}
} |
Once the file is loaded, we start getting our hands dirty. | function init(arrayBuffer) {
document.getElementById('instructions').innerHTML = 'Loading ...' |
Create a new | window.audioCtx = new webkitAudioContext()
window.analyser = audioCtx.createAnalyser() |
If a sound is still playing, stop it. | if (window.source)
source.noteOff(0) |
Decode the data in our array into an audio buffer | audioCtx.decodeAudioData(arrayBuffer, function(buffer) { |
Use the audio buffer with as our audio source | window.source = audioCtx.createBufferSource()
source.buffer = buffer |
Connect to the analyser ... | source.connect(analyser) |
and back to the destination, to play the sound after the analysis. | analyser.connect(audioCtx.destination) |
Start playing the buffer. | source.noteOn(0) |
Initialize a visualizer object | var viz = new simpleViz() |
Finally, initialize the visualizer. | new visualizer(viz['update'], analyser)
document.getElementById('instructions').innerHTML = ''
})
} |
The visualizer object.
Calls the | function visualizer(visualization, analyser) {
var self = this
this.visualization = visualization
var last = Date.now()
var loop = function() {
var dt = Date.now() - last |
we get the current byteFreq data from our analyser | var byteFreq = new Uint8Array(analyser.frequencyBinCount)
analyser.getByteFrequencyData(byteFreq)
last = Date.now() |
We might want to use a delta time ( | self.visualization(byteFreq, dt)
webkitRequestAnimationFrame(loop)
}
webkitRequestAnimationFrame(loop)
} |
A simple visualization. Its update function illustrates how to use the byte frequency data from an audioContext analyser. | function simpleViz(canvas) {
var self = this
this.canvas = document.getElementById('canvas')
this.ctx = this.canvas.getContext("2d")
this.copyCtx = document.getElementById('canvas-copy').getContext("2d")
this.ctx.fillStyle = '#fff'
this.barWidth = 10
this.barGap = 4 |
We get the total number of bars to display | this.bars = Math.floor(this.canvas.width / (this.barWidth + this.barGap)) |
This function is launched for each frame, together with the byte frequency data. | this.update = function(byteFreq) {
self.ctx.clearRect(0, 0, self.canvas.width, self.canvas.height) |
We take an element from the byteFreq array for each of the bars. Let's pretend our byteFreq contains 20 elements, and we have five bars... | var step = Math.floor(byteFreq.length / self.bars) |
| for (var i = 0; i < self.bars; i ++) { |
Draw each bar | var barHeight = byteFreq[i*step]
self.ctx.fillRect(
i * (self.barWidth + self.barGap),
self.canvas.height - barHeight,
self.barWidth,
barHeight)
self.copyCtx.clearRect(0, 0, self.canvas.width, self.canvas.height)
self.copyCtx.drawImage(self.canvas, 0, 0)
}
}
}
|