Skip to content
This repository has been archived by the owner on Oct 20, 2020. It is now read-only.

Commit

Permalink
Adds sounds example
Browse files Browse the repository at this point in the history
  • Loading branch information
cedricpinson committed Oct 13, 2016
1 parent 3897ea1 commit 3ebf53c
Show file tree
Hide file tree
Showing 6 changed files with 357 additions and 1 deletion.
76 changes: 76 additions & 0 deletions examples/sound-3d/index.html
@@ -0,0 +1,76 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sound3D</title>

<link rel="stylesheet" type="text/css" href="../templates/css/base.css">

<style type="text/css">
/* Custom CSS goes here */
<!-- #ViewContainer { -->
<!-- position: absolute; -->
<!-- } -->
<!-- #View { -->
<!-- display: block; -->
<!-- } -->
</style>


<!-- Javascript -->
<!-- Dependencies -->
<script type="text/javascript" src="../vendors/core.js"></script>
<script type="text/javascript" src="../vendors/core.js"></script>
<script type="text/javascript" src="../vendors/rStats.js"></script>
<script type="text/javascript" src="../vendors/rStats.extras.js"></script>
<script type="text/javascript" src="../vendors/jquery-2.1.1.js"></script>
<script type="text/javascript" src="../vendors/dat.gui.js"></script>
<script type="text/javascript" src="../vendors/bluebird.js"></script>
<script type="text/javascript" src="../vendors/hammer.js"></script>
<script type="text/javascript" src="../vendors/leap.js"></script>

<script type="text/javascript" src="https://connect.soundcloud.com/sdk.js"></script>
<!-- last version of the sdk does not work with firefox 49 on osx -->
<!-- <script type="text/javascript" src="https://connect.soundcloud.com/sdk/sdk-3.1.2.js"></script> -->

<!-- OGSJ main library -->
<script type="text/javascript" src="../../builds/dist/OSG.js"></script>

<!-- Example Base Class -->
<script type="text/javascript" src="../templates/Example.js"></script>

<!-- User/Example code-->
<script type="text/javascript">
window.osg = OSG.osg;
</script>
<script type="text/javascript" src="sound.js"></script>
<script type="text/javascript" src="main.js"></script>

</head>



<body class="osgjs-theme-dark">

<div id="ViewContainer" class="osgjs-fullpage">
<!-- very important change the size of the parent element instead-->
<canvas id="View" style="height:100%;width:100%;" oncontextmenu="return false;"></canvas>
</div>

<div class="osgjs-info osgjs-info-dark">

<a href="http://osgjs.org/" class="osgjs-powered" title="Powered by OSG.JS">
<img src="http://osgjs.org/assets/logo.png" alt="" width="32" height="32">
<strong>OSG.JS</strong>
</a>

<div class="osgjs-description">
3D spatial sounds example. Data are provided by <a href="https://soundcloud.com">soundcloud</a><br>
Use FPS controls to navigate in the scene
</div>

</div>

</body>

</html>
161 changes: 161 additions & 0 deletions 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 );

} )();
116 changes: 116 additions & 0 deletions 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;
};
} )()

};
1 change: 0 additions & 1 deletion sources/osg/ComputeMatrixFromNodePath.js
Expand Up @@ -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;
Expand Down
Binary file added website/contents/assets/img/sound3d.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions website/contents/examples.md
Expand Up @@ -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
Expand Down

0 comments on commit 3ebf53c

Please sign in to comment.