80 | Object-based audio is a revolutionary approach for creating and 81 | deploying interactive, personalised, scalable and immersive 82 | content, by representing it as a set of individual assets 83 | together with metadata describing their relationships and 84 | associations. 85 | This allows media objects to be assembled in ground-breaking ways to 86 | create new user experiences. With the introduction of HTML5 87 | and the Web Audio API, an important prerequisite was made for 88 | native rendering of object-based audio in modern browsers. 89 | 90 |
91 |106 | To play this demo, you need a modern browser which supports 107 | HTML5 and the Web Audio API. This is the case for all major 108 | browsers (Firefox, Chrome, Safari and Opera). Only Internet 109 | Explorer supports the Web Audio API only in Edge with Windows 110 | 10. You can check the support by visiting 111 | this page. 112 |
113 |115 | To start the demo, choose a scene from the list and press the play 116 | button left of it once the audio files are loaded. Depending 117 | on the capabilities of your browser, either m4a, ogg or mp3 118 | files will be downloaded. If your internet connection is rather slow 119 | and / or the audio files are rather large, it might take a while 120 | until you can start the demo. 121 |
122 |
124 | You can choose between simply Stereo rendering (default) and
125 | fancy headphone rendering by clicking the icon in the lower right
126 | corner.
127 |
128 | Note: If you are using the Internet Explorer "Edge", only
129 | Stereo rendering is supported currently.
130 |
135 | You can rotate the listener's orientation by positioning the
136 | mouse above the listener's icon and rotate the mousewheel up
137 | or down.
138 |
139 | One can also change the position of the listener within the
140 | scene by moving it while pressing the mouse button.
141 |
144 | By clicking the controls icon left of the rendering mode icon,
145 | you can acticate the interactve mode. Any scene commands will
146 | be ignored and you can change the position of objects.
147 |
148 | Furthermore, you can mute / unmute objects by double clicking
149 | them.
150 |
163 |
164 |No scene selected
180 |" + key + "
"); 261 | 262 | var pos = this.om.objects[key].getPosition(); 263 | this._changeUIObjectPosition(key, [pos[0], -1 * pos[2]]); 264 | var that = this; 265 | $("#"+key).draggable({ 266 | drag: _.throttle( 267 | function(event, ui){ 268 | var topleft = [ui.position.top, ui.position.left]; 269 | var xy = that._topleft2xy(topleft); 270 | that.om.objects[event.target.id].setPosition([xy[0], 0, -1 * xy[1]]); 271 | console.debug("Drag event position: " + topleft); 272 | }, 273 | 50) 274 | }); 275 | if (!this.om.objects[key].getStatus()){ 276 | this._displayObject(key, false); 277 | } 278 | } 279 | }, 280 | 281 | _removeObjects: function(){ 282 | for (var key in this.om.objects){ 283 | $("#"+key).remove(); 284 | } 285 | }, 286 | 287 | _setRoomSize: function(roomsize) { 288 | $(this.bg).css({"width": roomsize[0], "height": roomsize[1]}); 289 | this.roomsize = roomsize; 290 | }, 291 | 292 | _setListenerPosition: function(xy) { 293 | var topleft = this._xy2topleft(xy); 294 | $(this.listener).css({"top": topleft[0], "left": topleft[1]}); 295 | console.info("New listener position: " + topleft); 296 | var that = this; 297 | $(this.listener).draggable({ 298 | drag: function(event, ui){ 299 | var topleft = [ui.position.top, ui.position.left]; 300 | var xy = that._topleft2xy(topleft); 301 | that.om.setListenerPosition(xy[0], xy[1], 0); 302 | } 303 | }); 304 | }, 305 | 306 | _setListenerOrientation: function (angle){ 307 | // As x and y are somehow flipped, x needs to be calculated with sinus 308 | // and not with cosinus.. TODO: check why !? 309 | //var x = 32 * Math.sin(angle * (Math.PI / 180)); 310 | //var y = 32 * Math.cos(angle * (Math.PI / 180)); 311 | var x = 10 * Math.sin(angle * (Math.PI / 180)); 312 | var y = 0; // as we don't have a lattitude here y is always 0 :) 313 | var z = -10 * Math.cos(angle * (Math.PI / 180)); 314 | 315 | console.info("Set angle " + angle + " to new listener orientation " + x + " " + y + " " + z); 316 | this.om.setListenerOrientation(x, y, z); 317 | }, 318 | 319 | _changeUIObjectPosition: function(id, xy) { 320 | var topleft = this._xy2topleft(xy); 321 | $("#"+id).css({"top": topleft[0], "left": topleft[1]}); 322 | console.debug("New position of " + id + " is: " + topleft + "(xy: " + xy + ")"); 323 | }, 324 | 325 | _setObjPos: function(id, topleft){ 326 | var xy = this._topleft2xy(topleft); 327 | var xyz = [xy[0], xy[1], 0]; 328 | this.om.objects[id].setPostion(xyz); 329 | }, 330 | 331 | _xy2topleft: function(xy){ 332 | var topleft = [(-xy[1] * this._resizeFactor) + this.roomsize[1] / 2, 333 | (xy[0] * this._resizeFactor) + this.roomsize[0] / 2]; 334 | return topleft; 335 | }, 336 | 337 | _topleft2xy: function(topleft){ 338 | var xy = [-(this.roomsize[1] / 2 - topleft[1]) / this._resizeFactor, 339 | (this.roomsize[0] / 2 - topleft[0]) / this._resizeFactor]; 340 | return xy; 341 | }, 342 | 343 | _angle2xy: function(angle){ 344 | // For some reason, x needs to be calculated with sinus 345 | // and not with cosinus.. TODO: check why !? 346 | var x = 10 * Math.sin(angle * (Math.PI / 180)); 347 | var y = 0; 348 | var z = -10 * Math.cos(angle * (Math.PI / 180)); 349 | return [x, z]; 350 | }, 351 | 352 | _xyz2angle: function(xyz){ 353 | var angle = Math.atan2(xyz[0], -xyz[2]) / Math.PI * 180; 354 | return angle; 355 | } 356 | }; 357 | 358 | module.exports = UIManager; 359 | -------------------------------------------------------------------------------- /tools/Multichannel-Order_Browsertest.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IRT-Open-Source/bogJS/5059ac3f212a34c43b8235ef9d79f5b7831d2480/tools/Multichannel-Order_Browsertest.xlsx -------------------------------------------------------------------------------- /tools/create_channelOrder_testfiles.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mkdir -p tmp_wav 4 | 5 | declare -a frqs=(100.0 500.0 1000.0 2000.0 3000.0 4000.0 5000.0 6000.0 7000.0 8000.0 9000.0 10000.0 11000.0) 6 | 7 | chs=$1 8 | chs_internal=`expr $chs - 1` 9 | 10 | # Generate wav files with spoken trial and condition numbers 11 | for number in `seq 0 $chs_internal`; do 12 | sox -b 16 -n tmp_wav/"ch"$number".wav" synth 1.0 sin ${frqs[$number]} gain -9 13 | printf "." 14 | done 15 | 16 | printf "\n" 17 | 18 | 19 | new_wav=signals/order/$chs"chs".wav 20 | mp4_name=signals/order/`basename "$new_wav" .wav`.mp4 21 | opus_name=signals/order/`basename "$new_wav" .wav`.opus 22 | 23 | # Now merge all sinus wav files 24 | sox -b 16 -M tmp_wav/*.wav $new_wav 25 | 26 | 27 | if [ $chs -lt 3 ] 28 | then 29 | ffmpeg -i $new_wav -c:a libfdk_aac -cutoff 20000 $mp4_name 30 | elif [ $chs -eq 3 ] 31 | then 32 | afconvert -f mp4f -d aac@48000 -c 3 -l AAC_3_0 $new_wav -o $mp4_name 33 | elif [ $chs -eq 4 ] 34 | then 35 | afconvert -f mp4f -d aac@48000 -c 4 -l AAC_Quadraphonic $new_wav -o $mp4_name 36 | elif [ $chs -eq 5 ] 37 | then 38 | afconvert -f mp4f -d aac@48000 -c 5 -l AAC_5_0 $new_wav -o $mp4_name 39 | elif [ $chs -eq 6 ] 40 | then 41 | afconvert -f mp4f -d aac@48000 -c 6 -l AAC_6_0 $new_wav -o $mp4_name 42 | elif [ $chs -eq 7 ] 43 | then 44 | afconvert -f mp4f -d aac@48000 -c 7 -l AAC_7_0 $new_wav -o $mp4_name 45 | elif [ $chs -eq 8 ] 46 | then 47 | afconvert -f mp4f -d aac@48000 -c 8 -l AAC_Octagonal $new_wav -o $mp4_name 48 | else 49 | echo "=======================================================" 50 | echo "aac encoding not possible for this channel number" 51 | echo "=======================================================" 52 | fi 53 | 54 | 55 | oggenc $new_wav --advanced-encode-option disable_coupling=1 56 | 57 | # as the current version of opus-tools (0.1.9) does no more support the 58 | # uncoupled flag, we switched to the last working version (0.1.6) but using 59 | # the current libopus version (1.1.1). Moreover, we prevent updates for 60 | # opus-tools by "pinning" it with homebrew. You might want to "unpin" the 61 | # formula by executing 62 | # brew unpin opus-tools 63 | # NOTE: In case you might get into trouple in the future: http://stackoverflow.com/questions/3987683/homebrew-install-specific-version-of-formula 64 | opusenc --uncoupled $new_wav $opus_name 65 | 66 | 67 | 68 | #ffmpeg -i sync_test.mp4 -i $mp4_name -c:v copy -c:a copy -bsf:a aac_adtstoasc `basename "$new_wav" .wav`_vid.mp4 69 | #ffmpeg -i sync_test.webm -i $opus_name -c:v copy -c:a copy `basename "$new_wav" .wav`_vid.webm 70 | 71 | rm -r tmp_wav 72 | -------------------------------------------------------------------------------- /tools/encodeMultichannel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ## Required steps to make this script running (tested on OS X 10.11.2): 4 | # brew install opus-tools vorbis-tools 5 | # cd $( brew --prefix ) 6 | # brew unlink opus-tools 7 | # brew git checkout c2e5077062344a1ffb90f0b871bc574227e7790d Library/Formula/opus-tools.rb 8 | # OR 9 | # brew install https://raw.githubusercontent.com/kickermeister/homebrew-versions/patch-1/opus-tools.rb 10 | # brew install opus-tools 11 | # brew pin opus-tools 12 | 13 | chs=$1 14 | chs_internal=`expr $chs - 1` 15 | file=$2 16 | 17 | mp4_name=`basename "$file" .wav`.mp4 18 | opus_name=`basename "$file" .wav`.opus 19 | 20 | # Now merge all sinus wav files 21 | #sox -b 16 $file $file 22 | 23 | 24 | if [ $chs -lt 3 ] 25 | then 26 | ffmpeg -i $file -c:a libfdk_aac -cutoff 20000 $mp4_name 27 | elif [ $chs -eq 3 ] 28 | then 29 | afconvert -f mp4f -d aac@48000 -c 3 -l AAC_3_0 $file -o $mp4_name 30 | elif [ $chs -eq 4 ] 31 | then 32 | afconvert -f mp4f -d aac@48000 -c 4 -l AAC_Quadraphonic $file -o $mp4_name 33 | elif [ $chs -eq 5 ] 34 | then 35 | afconvert -f mp4f -d aac@48000 -c 5 -l AAC_5_0 $file -o $mp4_name 36 | elif [ $chs -eq 6 ] 37 | then 38 | afconvert -f mp4f -d aac@48000 -c 6 -l AAC_6_0 $file -o $mp4_name 39 | elif [ $chs -eq 7 ] 40 | then 41 | afconvert -f mp4f -d aac@48000 -c 7 -l AAC_7_0 $file -o $mp4_name 42 | elif [ $chs -eq 8 ] 43 | then 44 | afconvert -f mp4f -d aac@48000 -c 8 -l AAC_Octagonal $file -o $mp4_name 45 | else 46 | echo "=======================================================" 47 | echo "aac encoding not possible for this channel number" 48 | echo "=======================================================" 49 | fi 50 | 51 | 52 | oggenc $file --advanced-encode-option disable_coupling=1 53 | 54 | # as the current version of opus-tools (0.1.9) does no more support the 55 | # uncoupled flag, we switched to the last working version (0.1.6) but using 56 | # the current libopus version (1.1.2). This version supports the uncoupled 57 | # flag, but does not advertise it. 58 | # 59 | # This can be done by using an old Formula of opus-tools (0.1.6): 60 | # git checkout c2e5077062344a1ffb90f0b871bc574227e7790d /usr/local/Library/Formula/opus-tools.rb 61 | # 62 | # Moreover, we prevent updates for 63 | # opus-tools by "pinning" it with homebrew. You might want to "unpin" the 64 | # formula by executing 65 | # brew unpin opus-tools 66 | # NOTE: In case you might get into trouple in the future: http://stackoverflow.com/questions/3987683/homebrew-install-specific-version-of-formula 67 | opusenc --uncoupled $file $opus_name 68 | 69 | 70 | 71 | #ffmpeg -i sync_test.mp4 -i $mp4_name -c:v copy -c:a copy -bsf:a aac_adtstoasc `basename "$file" .wav`_vid.mp4 72 | #ffmpeg -i sync_test.webm -i $opus_name -c:v copy -c:a copy `basename "$file" .wav`_vid.webm 73 | 74 | -------------------------------------------------------------------------------- /tools/zip_demo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | zip bogJS_demo.zip ../css/* \ 4 | ../css/images/* \ 5 | ../fonts/* \ 6 | ../img/* \ 7 | ../demos/360/index.html \ 8 | ../demos/360/valiant360/css/valiant360.css \ 9 | ../demos/360/valiant360/jquery.valiant360.js \ 10 | ../demos/360/valiant360/js/three.min.js \ 11 | ../dist/bogJS-latest.* \ 12 | ../dist/bogJS-dev.* \ 13 | ../scenes/romeo_XYZconverted.spatdif \ 14 | ../scenes/debo.spatdif \ 15 | ../scenes/LongTrainRunning_short.spatdif \ 16 | ../scenes/Vulkane360_XYZconverted.spatdif \ 17 | -X -x *.wav .git* ../_site/ ../out/ ../doc/ zip_demo.sh bogJS_demo/ 18 | 19 | 20 | #tar --exclude='*.wav' \ 21 | # --exclude='.git*' \ 22 | # --exclude='_site/' \ 23 | # --exclude='out/' \ 24 | # --exclude='zip_demo.sh' \ 25 | # --exclude='index.html.developing' \ 26 | # -cvzf bogJS_demo.tar.gz css/* \ 27 | # css/images/* \ 28 | # fonts/* \ 29 | # img/* \ 30 | # js/* \ 31 | # scenes/romeo.spatdif \ 32 | # scenes/LongTrainRunning_short.spatdif \ 33 | # signals/romeo/* \ 34 | # signals/LongTrainRunning/* \ 35 | # ./* \ 36 | # ../html5_player/script/irtPlayer_new.js 37 | 38 | 39 | --------------------------------------------------------------------------------