From 3ebf53c1fe6ce15d1b126e48e0beae1d38940e5e Mon Sep 17 00:00:00 2001 From: Cedric Pinson Date: Wed, 5 Oct 2016 18:40:45 +0200 Subject: [PATCH] Adds sounds example --- examples/sound-3d/index.html | 76 +++++++++++ examples/sound-3d/main.js | 161 +++++++++++++++++++++++ examples/sound-3d/sound.js | 116 ++++++++++++++++ sources/osg/ComputeMatrixFromNodePath.js | 1 - website/contents/assets/img/sound3d.jpg | Bin 0 -> 22296 bytes website/contents/examples.md | 4 + 6 files changed, 357 insertions(+), 1 deletion(-) create mode 100644 examples/sound-3d/index.html create mode 100644 examples/sound-3d/main.js create mode 100644 examples/sound-3d/sound.js create mode 100644 website/contents/assets/img/sound3d.jpg diff --git a/examples/sound-3d/index.html b/examples/sound-3d/index.html new file mode 100644 index 000000000..c910e2e01 --- /dev/null +++ b/examples/sound-3d/index.html @@ -0,0 +1,76 @@ + + + + + Sound3D + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+ + + + OSG.JS + + +
+ 3D spatial sounds example. Data are provided by soundcloud
+ Use FPS controls to navigate in the scene +
+ +
+ + + + diff --git a/examples/sound-3d/main.js b/examples/sound-3d/main.js new file mode 100644 index 000000000..b7986bbac --- /dev/null +++ b/examples/sound-3d/main.js @@ -0,0 +1,161 @@ +( function () { + 'use strict'; + + var SoundCloudID = '237d195ad90846f5e6294ade2e8cf87b'; + + var P = window.P; + var OSG = window.OSG; + var osgText = OSG.osgText; + var osgGA = OSG.osgGA; + var osg = OSG.osg; + var ExampleOSGJS = window.ExampleOSGJS; + var SC = window.SC; + var SoundManager = window.SoundManager; + + var Example = function () { + + this._soundList = [ { + url: 'https://soundcloud.com/wearecc/mdg-banana-man', + pos: [ 15, 0, 0 ], + audio: undefined + }, { + url: 'https://soundcloud.com/kodak-black/kodak-black-22-no-flocking', + pos: [ -15, 0, 0 ], + audio: undefined + }, { + url: 'https://soundcloud.com/championdnb/true-survivor-champion', + pos: [ 0, -20, 0 ], + audio: undefined + } ]; + + ExampleOSGJS.call( this ); + this.initializeSoundCloud(); + + }; + + + Example.prototype = osg.objectInherit( ExampleOSGJS.prototype, { + + initializeSoundCloud: function () { + SC.initialize( { + client_id: SoundCloudID + } ); + }, + + // helpers + createSound: function ( sound ) { + + // create the audio element in the dom + var audio = document.createElement( 'audio' ); + sound.audio = audio; + audio.preload = 'auto'; + audio.crossOrigin = 'anonymous'; + + var url = sound.url; + var self = this; + var defer = P.defer(); + + SC.get( '/resolve', { + 'url': url + }, function ( soundCloudResult ) { + + if ( soundCloudResult.errors ) { + + var errors = ''; + for ( var i = 0; i < soundCloudResult.errors.length; i++ ) { + errors += soundCloudResult.errors[ i ].error_message + '\n'; + } + + defer.reject( errors ); + + } else { + + var soundCloudURL = soundCloudResult.stream_url + '?client_id=' + SoundCloudID; + osg.log( 'stream ' + soundCloudURL + ' ready' ); + + var soundUpdateCallback = self._soundManager.create3DSound( audio, soundCloudURL ); + sound.sound = soundUpdateCallback; + + defer.resolve( sound ); + } + } ); + + return defer.promise; + }, + + run: function () { + ExampleOSGJS.prototype.run.call( this ); + + this._viewer.getManipulator().strafeVertical( 5 ); + }, + + createScene: function () { + this._soundManager = new SoundManager(); + this._soundManager._camera = this._viewer.getCamera(); + + // the root node + var scene = new osg.Node(); + scene.getOrCreateStateSet().setAttributeAndModes( new osg.CullFace( 0 ) ); + scene.addUpdateCallback( this._soundManager ); + + var addSoundInScene = function ( sound ) { + + var node = new osg.MatrixTransform(); + var sphere = osg.createTexturedSphere( 1, 15, 15 ); + node.addChild( sphere ); + osg.mat4.fromTranslation( node.getMatrix(), sound.pos ); + scene.addChild( node ); + + node.addUpdateCallback( sound.sound ); + var strArray = sound.url.split( '/' ); + var text = strArray.slice( strArray.length - 2 ).join( '/' ); + var textNode = new osgText.Text( text ); + textNode.setAutoRotateToScreen( true ); + textNode.setPosition( osg.vec3.fromValues( 0, 0, 1.1 ) ); + textNode.setCharacterSize( 0.5 ); + node.addChild( textNode ); + + sound.sound.play(); + // if ( !window.soundsList ) window.soundsList = []; + // window.soundsList.push( sound ); + }; + + // window.soundManager = this._soundManager; + + var mt = new osg.MatrixTransform(); + var grid = osg.createGridGeometry( -30, -40, -3, + 60, 0, 0, + 0, 60, 0, + 15, 15 + ); + mt.addChild( grid ); + scene.addChild( mt ); + + this.getRootNode().addChild( scene ); + + this._manipulator = new osgGA.FirstPersonManipulator(); + this._viewer.setManipulator( this._manipulator ); + this._viewer.getManipulator().setNode( scene ); + this._viewer.getManipulator().computeHomePosition(); + + for ( var i = 0, l = this._soundList.length; i < l; i++ ) { + + var sound = this._soundList[ i ]; + this.createSound( sound ).then( addSoundInScene ).catch( osg.error ); + + } + + + } + + } ); + + window.addEventListener( 'load', function () { + + var example = new Example(); + example.run(); + window.example = example; + + }, true ); + +} )(); diff --git a/examples/sound-3d/sound.js b/examples/sound-3d/sound.js new file mode 100644 index 000000000..a3adf3d16 --- /dev/null +++ b/examples/sound-3d/sound.js @@ -0,0 +1,116 @@ + var Sound = function ( domElement, url, panner ) { + this._player = domElement; + this._mediaElement = undefined; + this._panner = panner; + this._player.setAttribute( 'src', url ); + }; + + Sound.prototype = { + + play: function () { + if ( this._player ) this._player.play(); + }, + + pause: function () { + if ( this._player ) this._player.pause(); + }, + + update: ( function () { + var matrixWorldSpace = osg.mat4.create(); + var position = osg.vec3.create(); + + return function ( node, nv ) { + + if ( !this._panner ) return true; + + osg.computeLocalToWorld( nv.nodePath, true, osg.mat4.identity( matrixWorldSpace ) ); + + osg.mat4.getTranslation( position, matrixWorldSpace ); + var soundPosition = this._panner; + soundPosition.setPosition( position[ 0 ], position[ 1 ], position[ 2 ] ); + return true; + + }; + + } )() + + }; + + + var SoundManager = function () { + this._context = new( window.AudioContext || window.webkitAudioContext ); + }; + + SoundManager.prototype = { + + create3DSound: function ( player, url ) { + var panner = this._context.createPanner(); + + panner.panningModel = 'HRTF'; + panner.distanceModel = 'inverse'; + panner.refDistance = 1; + panner.maxDistance = 1000; + panner.rolloffFactor = 1; + panner.coneInnerAngle = 360; + panner.coneOuterAngle = 0; + panner.coneOuterGain = 0; + panner.setPosition( 0, 0, 0 ); + + var sound = new Sound( player, url, panner ); + + // panner.orientationX.value = 1; + // panner.orientationY.value = 0; + // panner.orientationZ.value = 0; + // panner.positionX.value = 0.0; + // panner.positionY.value = 0.0; + // panner.positionZ.value = 0.0; + sound._panner = panner; + + var source = this._context.createMediaElementSource( player ); + sound._mediaElement = source; + + source.connect( panner ); + panner.connect( this._context.destination ); + return sound; + }, + + createAmbientSound: function ( player, url ) { + var sound = new Sound( player, url ); + sound._mediaElement = this._context.createMediaElementSource( player ); + return sound; + }, + + releaseSound: function ( sound ) { + if ( !sound ) return; + + sound.pause(); + if ( sound._mediaElement ) sound._mediaElement.disconnect( sound._panner ); + if ( sound._panner ) sound._panner.disconnect( this._context ); + sound._panner = undefined; + sound._mediaElement = undefined; + }, + + update: ( function () { + var eye = osg.vec3.create(); + var center = osg.vec3.create(); + var up = osg.vec3.create(); + + return function () { + + var camera = this._camera; + + if ( camera ) { + + osg.mat4.getLookAt( eye, center, up, camera.getViewMatrix() ); + osg.vec3.sub( center, center, eye ); + var listener = this._context.listener; + listener.setPosition( eye[ 0 ], eye[ 1 ], eye[ 2 ] ); + listener.setOrientation( center[ 0 ], center[ 1 ], center[ 2 ], up[ 0 ], up[ 1 ], up[ 2 ] ); + + } + + return true; + }; + } )() + + }; diff --git a/sources/osg/ComputeMatrixFromNodePath.js b/sources/osg/ComputeMatrixFromNodePath.js index a4aa8418f..6e9823925 100644 --- a/sources/osg/ComputeMatrixFromNodePath.js +++ b/sources/osg/ComputeMatrixFromNodePath.js @@ -3,7 +3,6 @@ var mat4 = require( 'osg/glMatrix' ).mat4; var TransformEnums = require( 'osg/TransformEnums' ); -// TODO: GC PERF: add a result Matrix Parameter. var computeLocalToWorld = function ( nodePath, ignoreCameras, userMatrix ) { var ignoreCamera = ignoreCameras; diff --git a/website/contents/assets/img/sound3d.jpg b/website/contents/assets/img/sound3d.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a25d13972e5ed24494f6bf0902ff38c8c148083c GIT binary patch literal 22296 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 literal 0 HcmV?d00001 diff --git a/website/contents/examples.md b/website/contents/examples.md index f2f4bcd82..161b66a65 100644 --- a/website/contents/examples.md +++ b/website/contents/examples.md @@ -2,6 +2,10 @@ title: SDK Examples samples: + - + title: 3D sounds + image: assets/img/sound3d.jpg + link: examples/sound-3d - title: PBR image: assets/img/pbr.jpg