webaudio.js has been first coded as a tQuery plugin.
You can find a post about it
on learningthreejs blog.
But this technology is so nice, it deserved its own repository.
The library gained in flexibility in the process: It is now possible to display histogram in canvas2D
of simply play sound, with no 3D at all :) see here for a list of
Web Audio API is aimed for games and based on openAL. Its API is real nice tho. It is Efficient and flexible. It is efficient because most processing happen in native code, still you configure it in js, your favorite language :) It is flexible as it is based on a routing concept which give you great controls on the sounds you play.
You can find many good tutorials on the matter on html5rocks. I recently did a presentation at musichackparis on Web Audio API. If you want to know more, slides are here. This API is available on WebKit based browser, so safari and chrome and its derivative. Unfortunatly this API isn’t compatible with major webgl browsers e.g. firefox and opera. The Web Audio API is real nice tho. Efficient flexible Sound is still the poor lone child of the web :( Well let’s have fun with what we have.
Let’s get started
1 2 3 4
Let’s Code in JS
First we gonna intenciate
WebAudio. This will initialize the layer.
It will create the AudioNode`s
for the end of the chain.
By default it contains a
The gainNode is used to tune the volume. and the compressNode to smooth the peaks we could
hit in the sound.
Now that we go webaudio available, let’s use it to create the sound we gonna play.
.createSound() will create a
WebAudio.Sound. Then we
from this url ‘sounds/perfume.mp3’. The callback will be notified as soon as the sound
is loaded. Then we simply start to play it. Don’t forget to get
thus the sound will loop forever.
1 2 3
Initialize the 3D World
First we initialize the world in 3D.
tQuery.createWorld(), we create a
.boilerplate(), we setup a boilerplate on this world. A boilerplate is
a fast way to get you started on the right foot. It is the
learningthreejs boilerplate for three.js
.start(), we start the rendering loop. So from now on, the world scene
gonna be rendered periodically, typically 60time per seconds.
We Change the background color. This confusing line ensure the background of the
3D scene will be rendered as
0x000000 color, aka black.
Here we setup the lights of our scene. This is a key factor for the look and feel of your scene. We add a ambient light and 2 directional lights.
1 2 3
First we initialize
nBar to store number of bars in our 3D vuemeter.
This number MUST be odd, thus the vuemeter is symteric with the middle
Now we need to compute the width of each 3D bar. The whole vuemeter is
80 wide. So each bar is
We create an array
bars3d. We will use it to store the object3D
for all bars of the histogram.
Build the 3D VueMeter
First we create the container group3D which gonna regroup all the bar3D. It is the container of the whole 3D Vuemeter
We gonna build each bar and add it to
We loop to create
tQuery.createCube(). In fact a bar
is a rectangular box, so like a cube with different dimensions.
a bar got a width of
barW, an height of 10 and a depth of 5.
The material is a simple lambert.
Once the bar is create, we add it to
group3d and set it to the correct
position in space.
We push every bar3d into
bars3d for future reference.
1 2 3 4 5 6 7 8
Update Vuemeter From Sound Analyser
Here we hook a function to tQuery rendering loop,
this function gonna be executed everytime our 3D scene is rendered.
if the sound isnt yet loaded, do nothing.
build the histogram of the sound based on
We gonna loop over each bar3D of our vuemeter. We gonna update each of them based on the sound histogram we just computed.
We need to determine which value in the histogram match this vuemeter bar. As our vuemeter is symetric, the vuemeter bar on the far left got the same histogram value as the one on the far right. This make this computation a bit confusing.
Now we need to compute the height of the vuemeter bar based on histogram value. This is simple scaling from one to the other: vuemeter height === histo height / 256
Now that we computed all that, we update the
bar3d. We update
to change its size and
.material.color to change its color. The formulas
i used “worked for me”. Up to you to be creative and find the one that fit
your own needs
1 2 3 4
That’s all folks. Have fun :)