1 /** 2 * The Render Engine 3 * Sound 4 * 5 * @fileoverview A sound object. 6 * 7 * @author: Brett Fattori (brettf@renderengine.com) 8 * @author: $Author: bfattori $ 9 * @version: $Revision: 1555 $ 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.resources.types.Sound", 36 "requires":[ 37 "R.engine.PooledObject" 38 ] 39 }); 40 41 /** 42 * @class Represents a sound object that is abstracted from the sound system. 43 * If the sound system does not initialize, for whatever reason, you can 44 * still call a sound's methods. 45 * 46 * @constructor 47 * @param name {String} The name of the sound 48 * @extends R.engine.PooledObject 49 */ 50 R.resources.types.Sound = function () { 51 return R.engine.PooledObject.extend(/** @scope R.resources.types.Sound.prototype */{ 52 53 volume:-1, 54 paused:false, 55 pan:-1, 56 muted:false, 57 soundObj:null, 58 soundSystem:null, 59 supportedType:false, 60 61 /** @private */ 62 constructor:function (soundSystem, soundObj) { 63 this.volume = 50; 64 this.paused = false; 65 this.pan = 0; 66 this.muted = false; 67 this.soundObj = soundObj; 68 this.soundSystem = soundSystem; 69 this.supportedType = true; 70 this.loop = false; 71 return this.base(name); 72 }, 73 74 /** 75 * Destroy the sound object 76 */ 77 destroy:function () { 78 this.soundSystem.destroySound(this.sound); 79 this.base(); 80 }, 81 82 /** 83 * Release the sound back into the pool for reuse 84 */ 85 release:function () { 86 this.base(); 87 this.volume = -1; 88 this.pan = -1; 89 this.paused = false; 90 this.muted = false; 91 this.soundObj = null; 92 this.soundSystem = null; 93 }, 94 95 /** 96 * Set a boolean flag indicating if the sound type is supported by the browser 97 * @param state {Boolean} <code>true</code> indicates the sound type is supported 98 */ 99 setSupportedTypeFlag:function (state) { 100 this.supportedType = state; 101 }, 102 103 /** 104 * Returns a boolean indicating if the sound type is supported by the browser 105 * @return {Boolean} 106 */ 107 getSupportedTypeFlag:function () { 108 return this.supportedType; 109 }, 110 111 /** 112 * Get the native sound object which was created by the subclassed sound system. 113 * @return {Object} 114 */ 115 getSoundObject:function () { 116 return this.soundObj; 117 }, 118 119 /** 120 * Set the sound object which the subclassed sound system created. 121 * @param soundObj {Object} The sound's native object 122 */ 123 setSoundObject:function (soundObj) { 124 this.soundObj = soundObj; 125 }, 126 127 /** 128 * Play the sound. If the volume is specified, it will set volume of the 129 * sound before playing. If the sound was paused, it will be resumed. 130 * 131 * @param volume {Number} <i>[optional]</i> An integer between 0 (muted) and 100 (full volume) 132 */ 133 play:function (volume) { 134 if (this.paused) { 135 this.resume(); 136 return; 137 } 138 139 if (volume && volume != this.getVolume()) { 140 this.setVolume(volume); 141 } 142 143 this.soundSystem.playSound(this.soundObj); 144 }, 145 146 /** 147 * If the sound is playing, stop the sound and reset it to the beginning. 148 */ 149 stop:function () { 150 this.paused = false; 151 this.soundSystem.stopSound(this.soundObj); 152 }, 153 154 /** 155 * If the sound is playing, pause the sound. 156 */ 157 pause:function () { 158 this.soundSystem.pauseSound(this.soundObj); 159 this.paused = true; 160 }, 161 162 /** 163 * Returns <tt>true</tt> if the sound is currently paused. 164 * @return {Boolean} <tt>true</tt> if the sound is paused 165 */ 166 isPaused:function () { 167 return this.paused; 168 }, 169 170 /** 171 * If the sound is paused, it will resume playing the sound. 172 */ 173 resume:function () { 174 this.paused = false; 175 this.soundSystem.resumeSound(this.soundObj); 176 }, 177 178 /** 179 * Mute the sound (set its volume to zero). 180 */ 181 mute:function () { 182 this.soundSystem.muteSound(this.soundObj); 183 this.muted = true; 184 }, 185 186 /** 187 * Unmute the sound (reset its volume to what it was before muting). 188 */ 189 unmute:function () { 190 if (!this.muted) { 191 return; 192 } 193 this.soundSystem.unmuteSound(this.soundObj); 194 this.muted = false; 195 }, 196 197 /** 198 * Set the volume of the sound to an integer between 0 (muted) and 100 (full volume). 199 * 200 * @param volume {Number} The volume of the sound 201 */ 202 setVolume:function (volume) { 203 if (isNaN(volume)) { 204 return; 205 } 206 207 // clamp it 208 volume = (volume < 0 ? 0 : volume > 100 ? 100 : volume); 209 this.volume = volume; 210 this.soundSystem.setSoundVolume(this.soundObj, volume); 211 }, 212 213 /** 214 * Get the volume the sound is playing at. 215 * @return {Number} An integer between 0 and 100 216 */ 217 getVolume:function () { 218 return this.volume; 219 }, 220 221 /** 222 * Set the pan of the sound, with -100 being full left and 100 being full right. 223 * 224 * @param pan {Number} An integer between -100 and 100, with 0 being center. 225 */ 226 setPan:function (pan) { 227 this.pan = pan; 228 this.soundSystem.setSoundPan(this.soundObj, pan); 229 }, 230 231 /** 232 * Get the pan of the sound, with -100 being full left and 100 being full right. 233 * @return {Number} An integer between -100 and 100 234 */ 235 getPan:function () { 236 return this.pan; 237 }, 238 239 /** 240 * Set the sound offset in milliseconds. 241 * 242 * @param millisecondOffset {Number} The offset into the sound to play from 243 */ 244 setPosition:function (millisecondOffset) { 245 this.position = millisecondOffset; 246 this.soundSystem.setSoundPosition(this.soundObj, millisecondOffset); 247 }, 248 249 /** 250 * Get the position of the sound, in milliseconds, from the start of the sound. 251 * @return {Number} The millisecond offset into the sound 252 */ 253 getLastPosition:function () { 254 return this.soundSystem.getSoundPosition(this.soundObj); 255 }, 256 257 /** 258 * Get the total size, in bytes, of the sound. If the sound engine is not 259 * initialized, returns 0. 260 * @return {Number} The size of the sound, in bytes 261 */ 262 getSizeBytes:function () { 263 return this.soundSystem.getSoundSize(this.soundObj); 264 }, 265 266 /** 267 * Get the length of the sound, in milliseconds. If the sound hasn't fully loaded, 268 * it will be the number of milliseconds currently loaded. Due to the nature of 269 * Variable Bitrate (VBR) sounds, this number may be inaccurate. 270 * @return {Number} The length of the sound, in milliseconds 271 */ 272 getDuration:function () { 273 return this.soundSystem.getSoundDuration(this.soundObj); 274 }, 275 276 /** 277 * Flag to indicate if the sound ready to use. 278 * @return {Boolean} 279 */ 280 getReadyState:function () { 281 return this.soundSystem.getSoundReadyState(this.soundObj); 282 } 283 284 }, /** @scope R.resources.types.Sound.prototype */ { 285 /** 286 * Gets the class name of this object. 287 * @return {String} The string "R.resources.types.Sound" 288 */ 289 getClassName:function () { 290 return "R.resources.types.Sound"; 291 } 292 }); 293 294 }