1 /* 2 *Copyright (c) 2009, TellurianRing.com 3 *All rights reserved. 4 * 5 *Redistribution and use in source and binary forms, with or without modification, 6 *are permitted provided that the following conditions are met: 7 * 8 * Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * Neither the name of the Organization (TellurianRing.com) nor the names of 14 * its contributors may be used to endorse or promote products derived from 15 * this software without specific prior written permission. 16 * 17 *THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 *ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 *WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 *DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 21 *ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 *(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 *LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 24 *ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 *(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 /** 29 * @class Loads some audio or sound into the Scene. This implementation uses the 30 * HTML 5 audio tag and therefore requires a compatible browser. 31 * @example 32 * var sound1 = Audio({ 33 * url: "http://www.tellurianring.com/sounds/laugh.ogg" 34 * }); 35 * sound1.play(); 36 * <div id="sound_example_1"></div> 37 * <script type="text/javascript"> 38 * var sound1 = Sound({ 39 * url: "http://www.tellurianring.com/sounds/laugh.ogg" 40 * }); 41 * Stage({ 42 * container_id: "sound_example_1", 43 * width: 100, height: 100, 44 * update_time: 500, 45 * scene: Scene({ 46 * content: [ sound1 ] 47 * }) 48 * }); 49 * function audio_1() { 50 * sound1.play(); 51 * } 52 * </script> 53 * <button onclick="audio_1()">Play It!</button> 54 * @example 55 * Relative URL's work as well: 56 * var sound2 = Audio({ url: "./sounds/ohhh.ogg" }); 57 * sound2.play(); 58 * <div id="sound_example_2"></div> 59 * <script type="text/javascript"> 60 * var sound2 = Sound({ url: "./sounds/ohhh.ogg" }); 61 * Stage({ 62 * container_id: "sound_example_2", 63 * width: 100, height: 100, 64 * update_time: 500, 65 * scene: Scene({ 66 * content: [ sound2 ] 67 * }) 68 * }); 69 * function audio_2() { 70 * sound2.play(); 71 * } 72 * </script> 73 * <button onclick="audio_2()">Play It!</button> 74 * @extends SceneContent 75 * @param {Object} _details A JSON object with the following properties: 76 * <table cellpadding="0" cellspacing="1" border="0" class="constructor_details"> 77 * <tr><th>Property</th> <th>Required</th> <th>Default</th></tr> 78 * <tr><td>loop</td> <td>no</td> <td>false</td></tr> 79 * <tr><td>start</td> <td>no</td> <td>false</td></tr> 80 * <tr><td>url</td> <td>yes</td> <td></td></tr> 81 * <tr><td>volume</td> <td>no</td> <td>1</td></tr> 82 * </table> 83 */ 84 function Sound(_details) { // {{{ 85 /** @constructs */ 86 function _Sound(_details) { // {{{ 87 // Private Members {{{ 88 var audio = document.createElement("audio"); 89 var loaded = false; 90 var loop = check(_details.loop, false); 91 var start = check(_details.start, false); 92 var url = _details.url; 93 var volume = check(_details.volume, 1); 94 95 // tries to preload the image at initialization. 96 audio.autoplay = start; 97 audio.loader = this; 98 audio.loop = loop; 99 audio.onload = function() { 100 this.loader.doLoad(); 101 }; 102 audio.volume = volume; 103 // }}} Private Members 104 105 // Public Members {{{ 106 /** 107 * Executed when the audio is actually loaded. 108 */ 109 this.doLoad = function() { 110 loaded = true; 111 if(exists(_details.onLoad)) { 112 _details.onLoad(); 113 } 114 } 115 // Overridden to load audio at load time instead of creation time. 116 this.load = function(_scene, _parent) { 117 this.loadBase(_scene, _parent); 118 audio.src = url; 119 audio.load() 120 } 121 /** 122 * Sets the volume to the initial volume, and starts the sound. 123 * @function 124 */ 125 this.play = function() { 126 audio.play(); 127 } 128 /** 129 * Pauses the sound. 130 * @function 131 */ 132 this.pause = function() { 133 audio.pause(); 134 } 135 /** 136 * Sets the looping of this Sound. 137 * @function 138 * @param {Boolean} _loop Turns looping on for this sound - true or false. 139 */ 140 this.setLoop = function(_loop) { 141 loop = _loop; 142 audo.loop = _loop; 143 } 144 /** 145 * Sets the volume on this Sound. 146 * @function 147 * @param {Decimal} _volume Volume of sound between 0.0 and 1.0 148 */ 149 this.setVolume = function(_volume) { 150 volume = _volume; 151 audo.volume = _volume; 152 } 153 /** 154 * Stops the sound. This implementation pauses the sound and resets it. 155 */ 156 this.stop = function() { 157 this.pause(); 158 audio.currentTime = 0; 159 } 160 // Overridden to react to stage unloads - which cause the sound to stop. 161 this.update = function(_runtime) { 162 if(this.getStage().isRunning() == false) { 163 this.pause(); 164 } 165 } 166 // }}} Public Members 167 }// }}} _Sound 168 SceneContent(_details).extend(_Sound); 169 var theSound = new _Sound(_details); 170 return theSound; 171 } // }}} Sound 172 // These properties are for jEdit - Programmer's Text Editor. 173 // Load this file in jEdit to see what they do. 174 // ::folding=explicit:mode=javascript:noTabs=true:collapseFolds=4:: 175