We will try to make an 8D audio effect with ThreeJS editor. An 8D music is produced by adding panning, reverb and other sound effects to the audio file but here we'll create a dynamic 8D audio effect using threeJs "THREE.PositionalAudio" object.
First, fire up the threeJs editor found here. Add A box object and attach a script to it on the lower right corner.
Next, add a sphere or any 3d object you want it does not matter and set its position to the right of the box about 2 units. Now, we need to make it a child of the box by dragging the sphere handle under the box handle on the SCENE tree view on the upper right corner of the editor. Add a script to the sphere 3d object like what we did on the box 3d object.
The Box (parent) script:
player.listener = null
var tOld = 0
var rotX = 1
var rotY = 1
var rotZ = 1
function update( event ) {
var ds = new Date().getSeconds()
var dn = Date.now()
if(tOld < dn) {
tOld = dn+5000
rotX = ds % 4 == 0 ? 1 : 0
rotY = ds % 3 == 0 ? 1 : 0
rotZ = ds % 2 == 0 ? 1 : 0
console.log(rotX, rotY, rotZ)
console.log(tOld, dn, ds)
}
this.rotateOnAxis(new THREE.Vector3(rotX,rotY,rotZ), deg2rad(.1))
}
function init(){
player.listener = new THREE.AudioListener();
console.log(player)
this.add(player.listener)
}
First we set the player.listener to null then on the init hook we set the THREE.audioListener to the player.listener so it can be accessible on the sphere script child.
function init(){
player.listener = new THREE.AudioListener();
console.log(player)
this.add(player.listener)
}
Next, we initialize tOld, rotX, rotY, rotZ. We will use this later for our random rotations. We get the current seconds from the Date() class and the current milliseconds from Date.now() function.
If the old time (tOld) is still greater than the new milliseconds, do not adjust the rotation settings. This will renew every 5 seconds.
Finally, we rotate the box 3d object.
this.rotateOnAxis(new THREE.Vector3(rotX,rotY,rotZ), deg2rad(.1))
The Sphere script:
function init(){
console.log('ball', player)
var i = setInterval( () => {
if(player.listener === null) return
player.sound = new THREE.PositionalAudio( player.listener );
this.add(player.sound)
const audioLoader = new THREE.AudioLoader();
audioLoader.load( 'https://cdn.jsdelivr.net/gh/ellenprobst/web-audio-api-with-Threejs@57582104/lib/TheWarOnDrugs.m4a', function( buffer ) {
player.sound.setBuffer( buffer );
player.sound.setLoop( false );
player.sound.setVolume( 1 );
player.sound.play();
});
console.log('loaded sound!')
if(player.listener !== null){
clearInterval(i)
}
}, 1000)
}
function stop(){
player.sound.stop()
}
What the script does:
On init hook, we set player.listener global variable to THREE.PositionalAudio onto player.sound which is gonna be another global variable. We need this so we can stop the audio on stop hook. then load the audio file and set its buffer, loop, volume and finally play it.
Now you can enjoy 8D positional audio with your own mp4 or ogg music files.
Check out the demo!
Top comments (0)