Posted By

orazal on 10/31/08


Tagged

sound


Versions (?)

Who likes this?

1 person have marked this snippet as a favorite

Demian


SoundLoader


 / Published in: ActionScript
 

  1. import mx.events.EventDispatcher;
  2. import mx.utils.Delegate;
  3.  
  4.  
  5. /**
  6.  * Loads a list of sounds "in the background" without playing them
  7.  * Allows client to request a specific sound in priority
  8.  *
  9.  * Usage
  10.  *
  11.  * var soundLoader:SoundLoader = new SoundLoader(this,
  12.  * "soundLoader",
  13.  * this.getNextHighestDepth());
  14.  * soundLoader.addEventListener("loadProgress",
  15.  * Delegate.create(this,
  16.  * soundLoaderLoading));
  17.  * soundLoader.addEventListener("doneLoading",
  18.  * Delegate.create(this,
  19.  * soundLoaderLoaded));
  20.  * function soundLoaderLoading(event:Object)
  21.  * {
  22.  * trace("Loading " + Math.round(event.percent * 100) + " out of " + Math.round(event.globalPercent * 100));
  23.  * }
  24.  * function soundLoaderLoaded(event:Object)
  25.  * {
  26.  * trace("soundLoader doneLoading");
  27.  * }
  28.  *
  29.  * // Add sounds to queue
  30.  * soundLoader.push("audio/audio10.mp3");
  31.  * soundLoader.push("audio/audio11.mp3");
  32.  * soundLoader.push("audio/audio20.mp3");
  33.  *
  34.  * // Start the load queue
  35.  * soundLoader.startLoad();
  36.  *
  37.  * // Request a sound in priority
  38.  * var soundHandler:Object = {};
  39.  * soundHandler.soundLoaded = function(event:Object):Void
  40.  * {
  41.  * soundLoader.removeEventListener("soundLoaded", this);
  42.  * trace("Priority sound loaded");
  43.  * }
  44.  * soundLoader.addEventListener("soundLoaded", soundHandler);
  45.  * // Retrieve sound by file name (no path or extension)
  46.  * soundLoader.getSound("audio20");
  47.  *
  48.  */
  49.  
  50.  
  51. class com.orazal.SoundLoader
  52. {
  53. public var dispatchEvent:Function;
  54. public var addEventListener:Function;
  55. public var removeEventListener:Function;
  56.  
  57. private var sprite:MovieClip;
  58. private var soundList:Array /* of Object */;
  59. private var current:Number;
  60. private var interval:Number;
  61. private var prioritySound:Sound;
  62. private var priorityPosition:Number;
  63. private var loadingPriority:Boolean;
  64.  
  65. /**
  66. * Constructor, assign sounds to a movieclip to be able to control volume independently
  67. * of _root
  68. *
  69. * @param target
  70. * @param name
  71. * @param depth
  72. */
  73. public function SoundLoader(target:MovieClip, name:String, depth:Number)
  74. {
  75. EventDispatcher.initialize(this);
  76. sprite = target.createEmptyMovieClip(name, depth);
  77. soundList = [];
  78. loadingPriority = false;
  79. }
  80.  
  81. /**
  82. * Adds a sound url to load queue creating a new sound for the url
  83. * and assigning the sound a specific id
  84. * @param url
  85. */
  86. public function push(url:String):Void
  87. {
  88. // Retrieve file name only
  89. var id:String = url.slice(url.indexOf("/")+1, url.indexOf("."));
  90. var newSound:Sound = new Sound(sprite);
  91. newSound.onLoad = Delegate.create(this, onLoad);
  92. soundList.push( { url:url, sound:newSound, loaded:false , id:id} );
  93. }
  94.  
  95. /**
  96. * Start sound loading
  97. */
  98. public function startLoad():Void
  99. {
  100. current = 0;
  101. Sound(soundList[0].sound).loadSound(String(soundList[0].url));
  102. interval = setInterval(Delegate.create(this, checkProgress), 100);
  103. }
  104.  
  105.  
  106. /**
  107. * Sets volume for sprite
  108. */
  109. public function setVolume(value:Number):Void
  110. {
  111. sprite.setVolume(value);
  112. // extra sure
  113. for(var p:String in soundList)
  114. {
  115. Sound(soundList[p].sound).setVolume(value);
  116. }
  117.  
  118. }
  119.  
  120. /**
  121. * Retrieves a sound by id
  122. */
  123. public function getSound(id:String):Void
  124. {
  125. // Retrieve sound position
  126. for (var i:Number = 0; i < soundList.length; i++)
  127. {
  128. if (String(soundList[i].id) == id)
  129. {
  130. priorityPosition = i;
  131. break;
  132. }
  133. }
  134.  
  135. // Either dispatch get sound event or load specific sound
  136. // as a priority
  137. if (soundList[priorityPosition].loaded)
  138. {
  139. dispatchGetSound();
  140. }
  141. else
  142. {
  143. loadSoundPriority(priorityPosition);
  144. }
  145. }
  146.  
  147. /**
  148. * Changes load priority flag to stop loading other sounds
  149. * Uses a specific sound and load handler to load sound
  150. * Resumes load queue after sound has been loaded
  151. *
  152. * @param position
  153. */
  154. private function loadSoundPriority(position:Number):Void
  155. {
  156. loadingPriority = true;
  157. prioritySound = new Sound(sprite);
  158. prioritySound.onLoad = Delegate.create(this, onLoadPriority);
  159. prioritySound.loadSound(String(soundList[priorityPosition].url));
  160. }
  161.  
  162. /**
  163. * Priority sound onLoad handler
  164. */
  165. private function onLoadPriority(success:Boolean):Void
  166. {
  167.  
  168. continueLoading();
  169.  
  170. // update loading status
  171. soundList[priorityPosition].loaded = true;
  172. // replace original sound with priority sound
  173. soundList[priorityPosition].sound = prioritySound;
  174. dispatchGetSound();
  175. }
  176.  
  177. /**
  178. * Dispatches an event when a specific sound that has been requested has
  179. * finishes loading
  180. */
  181. private function dispatchGetSound():Void
  182. {
  183. var event:Object = { target:this, type:"soundLoaded" };
  184. event.sound = Sound(soundList[priorityPosition].sound);
  185. event.id = String(soundList[priorityPosition].id);
  186. dispatchEvent(event);
  187. }
  188.  
  189. /**
  190. * Continues load queue
  191. */
  192. private function continueLoading():Void
  193. {
  194. loadingPriority = false;
  195. // If current is not loaded it will automatically load next
  196. // when loaded or call finishLoading if it's last on list
  197. if(soundList[current].loaded)
  198. {
  199.  
  200. if (current < soundList.length - 1)
  201. {
  202. loadNext();
  203. }
  204. }
  205.  
  206. }
  207.  
  208. /**
  209. * Loads next sound in queue
  210. * @param success
  211. */
  212. private function loadNext():Void
  213. {
  214. // Make sure that there's a next sound to load
  215. if (current + 1 <= soundList.length - 1)
  216. {
  217. current++;
  218. Sound(soundList[current].sound).loadSound(String(soundList[current].url), false);
  219. }
  220. }
  221.  
  222. /**
  223. * Sound onLoad handler used for load queue
  224. *
  225. * @param success
  226. */
  227. private function onLoad(success:Boolean):Void
  228. {
  229.  
  230. // update loading status
  231. soundList[current].loaded = true;
  232.  
  233. if (current == soundList.length - 1)
  234. {
  235. finishLoading();
  236. return;
  237. }
  238.  
  239. if (loadingPriority)
  240. {
  241. // onLoadPriority will resume loading
  242. return;
  243. }
  244.  
  245. if (current < soundList.length - 1)
  246. {
  247. loadNext();
  248. }
  249.  
  250. }
  251.  
  252. /**
  253. * Stop checking sound load and dispatches event
  254. */
  255. private function finishLoading():Void
  256. {
  257. clearInterval(interval);
  258. var event:Object = { target:this, type:"doneLoading" };
  259. dispatchEvent(event);
  260.  
  261. }
  262.  
  263. /**
  264. * Checks current sound loading percent and total percent
  265. */
  266. private function checkProgress():Void
  267. {
  268.  
  269. var currentSound:Sound = Sound(soundList[current].sound);
  270. var percent:Number = currentSound.getBytesLoaded() / currentSound.getBytesTotal();
  271. // Determine percentage
  272. var loadedPercent:Number = current/soundList.length;
  273. var globalPercent = (percent/soundList.length)+loadedPercent;
  274.  
  275. // Dispatch event
  276. var event:Object = { target:this, type:"loadProgress" };
  277. event.current = current;
  278. event.percent = percent;
  279. event.globalPercent = globalPercent;
  280. dispatchEvent(event);
  281.  
  282. if(globalPercent == 1)
  283. {
  284. clearInterval(interval);
  285. }
  286. }
  287.  
  288. }

Report this snippet  

You need to login to post a comment.