1 /** 2 * The Render Engine 3 * SM2 4 * 5 * @fileoverview The SoundManager 2 sound system. 6 * 7 * @author: Brett Fattori (brettf@renderengine.com) 8 * @author: $Author: bfattori@gmail.com $ 9 * @version: $Revision: 1562 $ 10 * 11 * Copyright (c) 2011 Brett Fattori (brettf@renderengine.com) 12 * 13 * Permission is hereby granted, free of charge, to any person obtaining a copy 14 * of this software and associated documentation files (the "Software"), to deal 15 * in the Software without restriction, including without limitation the rights 16 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 * copies of the Software, and to permit persons to whom the Software is 18 * furnished to do so, subject to the following conditions: 19 * 20 * The above copyright notice and this permission notice shall be included in 21 * all copies or substantial portions of the Software. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 * THE SOFTWARE. 30 * 31 */ 32 33 // The class this file defines and its required classes 34 R.Engine.define({ 35 "class":"R.sound.SM2", 36 "requires":[ 37 "R.sound.AbstractSoundSystem" 38 ], 39 "includes":[ 40 "/libs/soundmanager2.js", 41 "/libs/AC_OETags.js" 42 ] 43 }); 44 45 /** 46 * @class Initializes the SoundManager2 sound system. The SoundManager2 sound system will only 47 * render MP3 audio as supported by Flash. 48 * 49 * @constructor 50 * @extends R.sound.AbstractSoundSystem 51 */ 52 R.sound.SM2 = function () { 53 return R.sound.AbstractSoundSystem.extend(/** @scope R.sound.SM2.prototype */{ 54 55 init:false, 56 soundManager:null, 57 58 /** @private */ 59 constructor:function () { 60 this.base(); 61 if (typeof SoundManager !== "undefined") { 62 63 // Create a link to the object 64 this.soundManager = window.soundManager; 65 this.soundManager.debugMode = false; 66 67 // directory where SM2 .SWFs live 68 this.soundManager.url = R.Engine.getEnginePath() + '/libs/'; 69 70 var swfVer = GetSwfVer(); 71 if (swfVer && swfVer != -1) { 72 // Detect the version of flash available. If 9 or higher, use 9 73 var hasReqestedVersion = DetectFlashVer(9, 0, 0); 74 if (hasReqestedVersion) { 75 this.soundManager.flashVersion = 9; 76 } 77 else { 78 this.soundManager.flashVersion = 8; 79 } 80 81 // Debugging enabled? 82 this.soundManager.debugMode = R.engine.Support.checkBooleanParam("debugSound"); 83 84 var self = this; 85 86 /** @private */ 87 this.soundManager.onload = function () { 88 self.init = true; 89 R.debug.Console.warn("SoundManager loaded successfully"); 90 self.makeReady(); 91 }; 92 93 /** @private */ 94 this.soundManager.onerror = function () { 95 self.init = false; 96 R.debug.Console.warn("SoundManager not loaded"); 97 }; 98 99 if (R.Engine.getEnginePath().indexOf("file:") == 0) { 100 this.soundManager.sandbox.type = "localWithFile"; 101 } 102 103 this.soundManager.go(); 104 105 } 106 else { 107 // Flash not installed 108 R.debug.Console.warn("SoundManager failed: No Flash Installed"); 109 this.init = false; 110 } 111 112 } 113 else { 114 // SoundManager isn't defined 115 R.debug.Console.warn("SoundManager failed: Not loaded or defined"); 116 this.init = false; 117 } 118 }, 119 120 /** 121 * Shutdown the sound system 122 * @private 123 */ 124 shutdown:function () { 125 this.soundManager.destruct(); 126 }, 127 128 /** 129 * Retrieve the sound from the network, when the sound system is ready, and create the sound object. 130 * @param resourceLoader {R.resources.loades.SoundLoader} The sound resource loader 131 * @param name {String} The name of the sound object 132 * @param url {String} The URL of the sound to load 133 * @return {R.resources.types.Sound} The sound object 134 * @private 135 */ 136 retrieveSound:function (resourceLoader, name, url) { 137 // See if the sound object is already cached by the given name 138 var sound = this.base(resourceLoader, name, url); 139 140 if (sound.getSoundObject() == null) { 141 // Nope, this is a new sound object 142 143 // Only MP3 files are supported 144 if (url.indexOf(".mp3") == -1) { 145 sound.setSupportedTypeFlag(false); 146 return sound; 147 } 148 149 if (!this.init) { 150 return sound; 151 } 152 153 // Create the sound object 154 var sm2sound = this.soundManager.createSound({ 155 "id":name, 156 "url":url, 157 "autoPlay":false, 158 "autoLoad":true, 159 "volume":50 160 }); 161 sound.setSoundObject(sm2sound); 162 } 163 164 return sound; 165 }, 166 167 /** 168 * Destroy the given sound object 169 * @param sound {R.resources.types.Sound} The sound object 170 */ 171 destroySound:function (sound) { 172 if (!(this.init && this.getSoundReadyState(sound))) { 173 return; 174 } 175 sound.unload(); 176 }, 177 178 /** 179 * Play the given sound object 180 * @param sound {R.resources.types.Sound} The sound object 181 */ 182 playSound:function (sound) { 183 if (!(this.init && this.getSoundReadyState(sound))) { 184 return; 185 } 186 sound.play(); 187 }, 188 189 /** 190 * Stop the given sound object 191 * @param sound {R.resources.types.Sound} The sound object 192 */ 193 stopSound:function (sound) { 194 if (!(this.init && this.getSoundReadyState(sound))) { 195 return; 196 } 197 sound.stop(); 198 }, 199 200 /** 201 * Pause the given sound object 202 * @param sound {R.resources.types.Sound} The sound object 203 */ 204 pauseSound:function (sound) { 205 if (!(this.init && this.getSoundReadyState(sound))) { 206 return; 207 } 208 sound.pause(); 209 }, 210 211 /** 212 * Resume the given sound object 213 * @param sound {R.resources.types.Sound} The sound object 214 */ 215 resumeSound:function (sound) { 216 if (!(this.init && this.getSoundReadyState(sound))) { 217 return; 218 } 219 sound.resume(); 220 }, 221 222 /** 223 * Mute the given sound object 224 * @param sound {R.resources.types.Sound} The sound object 225 */ 226 muteSound:function (sound) { 227 if (!(this.init && this.getSoundReadyState(sound))) { 228 return; 229 } 230 sound.mute(); 231 }, 232 233 /** 234 * Unmute the given sound object 235 * @param sound {R.resources.types.Sound} The sound object 236 */ 237 unmuteSound:function (sound) { 238 if (!(this.init && this.getSoundReadyState(sound))) { 239 return; 240 } 241 sound.unmute(); 242 }, 243 244 /** 245 * Set the volume of the given sound object 246 * @param sound {R.resources.types.Sound} The sound object 247 * @param volume {Number} A value between 0 and 100, with 0 being muted 248 */ 249 setSoundVolume:function (sound, volume) { 250 if (!(this.init && this.getSoundReadyState(sound))) { 251 return; 252 } 253 sound.setVolume(volume); 254 }, 255 256 /** 257 * Pan the given sound object from left to right 258 * @param sound {R.resources.types.Sound} The sound object 259 * @param pan {Number} A value between -100 and 100, with -100 being full left 260 * and zero being center 261 */ 262 setSoundPan:function (sound, pan) { 263 if (!(this.init && this.getSoundReadyState(sound))) { 264 return; 265 } 266 sound.setPan(pan); 267 }, 268 269 /** 270 * Set the position, within the sound's length, to play at 271 * @param sound {R.resources.types.Sound} The sound object 272 * @param millisecondOffset {Number} The millisecond offset from the start of 273 * the sounds duration 274 */ 275 setSoundPosition:function (sound, millisecondOffset) { 276 if (!(this.init && this.getSoundReadyState(sound))) { 277 return; 278 } 279 sound.setPosition(millisecondOffset); 280 }, 281 282 /** 283 * Get the position, in milliseconds, within a playing or paused sound 284 * @param sound {R.resources.types.Sound} The sound object 285 * @return {Number} 286 */ 287 getSoundPosition:function (sound) { 288 if (!(this.init && this.getSoundReadyState(sound))) { 289 return 0; 290 } 291 return sound.position; 292 }, 293 294 /** 295 * Get the size of the sound object, in bytes 296 * @param sound {R.resources.types.Sound} The sound object 297 * @return {Number} 298 */ 299 getSoundSize:function (sound) { 300 if (!(this.init && this.getSoundReadyState(sound))) { 301 return 0; 302 } 303 return sound.bytesTotal; 304 }, 305 306 /** 307 * Get the length (duration) of the sound object, in milliseconds 308 * @param sound {R.resources.types.Sound} The sound object 309 * @return {Number} 310 */ 311 getSoundDuration:function (sound) { 312 if (!(this.init && this.getSoundReadyState(sound))) { 313 return 0; 314 } 315 return sound.duration; 316 }, 317 318 /** 319 * Determine if the sound object is ready to be used 320 * @param sound {R.resources.types.Sound} The sound object 321 * @return {Boolean} <code>true</code> if the sound is ready 322 */ 323 getSoundReadyState:function (sound) { 324 if (!this.init) { 325 return true; 326 } 327 if (!sound) { 328 return false; 329 } 330 return (sound.readyState == R.sound.SM2.LOAD_SUCCESS); 331 } 332 333 }, { 334 LOAD_LOADING:1, 335 LOAD_ERROR:2, 336 LOAD_SUCCESS:3 337 }); 338 339 };