/src/away3d/audio/Sound3D.as

http://github.com/away3d/away3d-core-fp11 · ActionScript · 206 lines · 101 code · 23 blank · 82 comment · 3 complexity · 6c195599e6a584a73be63a84d8ae1ddb MD5 · raw file

  1. package away3d.audio
  2. {
  3. import away3d.audio.drivers.*;
  4. import away3d.containers.ObjectContainer3D;
  5. import away3d.events.Object3DEvent;
  6. import flash.events.Event;
  7. import flash.geom.*;
  8. import flash.media.*;
  9. /**
  10. * Dispatched when end of sound stream is reached (bubbled from the internal sound object).
  11. */
  12. [Event(name="soundComplete", type="flash.events.Event")]
  13. /**
  14. * <p>A sound source/emitter object that can be positioned in 3D space, and from which all audio
  15. * playback will be transformed to simulate orientation.</p>
  16. *
  17. * <p>The Sound3D object works much in the same fashion as primitives, lights and cameras, in that
  18. * it can be added to a scene and positioned therein. It is the main object, in the 3D sound API,
  19. * which the programmer will interact with.</p>
  20. *
  21. * <p>Actual sound transformation is performed by a driver object, which is defined at the time of
  22. * creation by the driver ini variable, the default being a simple pan/volume driver.</p>
  23. *
  24. * @see SimplePanVolumeDriver
  25. */
  26. public class Sound3D extends ObjectContainer3D
  27. {
  28. private var _refv:Vector3D;
  29. private var _driver:ISound3DDriver;
  30. private var _reference:ObjectContainer3D;
  31. private var _sound:Sound;
  32. private var _paused:Boolean;
  33. private var _playing:Boolean;
  34. /**
  35. * Create a Sound3D object, representing the sound source used for playback of a flash Sound object.
  36. *
  37. * @param sound The flash Sound object that is played back from this Sound3D object's position.
  38. * For realistic results, this should be a <em>mono</em> (single-channel, non-stereo) sound stream.
  39. * @param reference The reference, or "listener" object, typically a camera.
  40. * @param driver Sound3D driver to use when applying simulation effects. Defaults to SimplePanVolumeDriver.
  41. * @param init [optional] An initialisation object for specifying default instance properties.
  42. */
  43. public function Sound3D(sound:Sound, reference:ObjectContainer3D, driver:ISound3DDriver = null, volume:Number = 1, scale:Number = 1000)
  44. {
  45. _sound = sound;
  46. _reference = reference;
  47. _driver = driver || new SimplePanVolumeDriver();
  48. _driver.sourceSound = _sound;
  49. _driver.volume = volume;
  50. _driver.scale = scale;
  51. _driver.addEventListener(Event.SOUND_COMPLETE, onSoundComplete);
  52. addEventListener(Object3DEvent.SCENE_CHANGED, onSceneChanged);
  53. addEventListener(Object3DEvent.SCENETRANSFORM_CHANGED, onSceneTransformChanged);
  54. _reference.addEventListener(Object3DEvent.SCENETRANSFORM_CHANGED, onSceneTransformChanged);
  55. }
  56. /**
  57. * Defines the overall (master) volume of the 3D sound, after any
  58. * positional adjustments to volume have been applied. This value can
  59. * equally well be cotrolled by modifying the volume property on the
  60. * driver used by this Sound3D instance.
  61. *
  62. * @see ISound3DDriver.volume
  63. */
  64. public function get volume():Number
  65. {
  66. return _driver.volume;
  67. }
  68. public function set volume(val:Number):void
  69. {
  70. _driver.volume = val;
  71. }
  72. /**
  73. * Defines a scale value used by the driver when adjusting sound
  74. * intensity to simulate distance. The default number of 1000 means
  75. * that sound volume will near the hearing threshold as the distance
  76. * between listener and sound source approaches 1000 Away3D units.
  77. *
  78. * @see ISound3DDriver.scale
  79. */
  80. public function get scaleDistance():Number
  81. {
  82. return _driver.scale;
  83. }
  84. public function set scaleDistance(val:Number):void
  85. {
  86. _driver.scale = val;
  87. }
  88. /**
  89. * Returns a boolean indicating whether or not the sound is currently
  90. * playing.
  91. */
  92. public function get playing():Boolean
  93. {
  94. return _playing;
  95. }
  96. /**
  97. * Returns a boolean indicating whether or not playback is currently
  98. * paused.
  99. */
  100. public function get paused():Boolean
  101. {
  102. return _paused;
  103. }
  104. /**
  105. * Start (or resume, if paused) playback.
  106. */
  107. public function play():void
  108. {
  109. _playing = true;
  110. _paused = false;
  111. _driver.play();
  112. }
  113. /**
  114. * Pause playback. Resume using play().
  115. */
  116. public function pause():void
  117. {
  118. _playing = false;
  119. _paused = true;
  120. _driver.pause();
  121. }
  122. /**
  123. * Stop and rewind sound file. Replay (from the beginning) using play().
  124. * To temporarily pause playback, allowing you to resume from the same point,
  125. * use pause() instead.
  126. *
  127. * @see pause()
  128. */
  129. public function stop():void
  130. {
  131. _playing = false;
  132. _paused = false;
  133. _driver.stop();
  134. }
  135. /**
  136. * Alternate between pausing and resuming playback of this sound. If called
  137. * while sound is paused (or stopped), this will resume playback. When
  138. * called during playback, it will pause it.
  139. */
  140. public function togglePlayPause():void
  141. {
  142. if (_playing)
  143. this.pause();
  144. else
  145. this.play();
  146. }
  147. /**
  148. * @internal
  149. * When scene changes, mute if object was removed from scene.
  150. */
  151. private function onSceneChanged(ev:Object3DEvent):void
  152. {
  153. trace('scene changed');
  154. // mute driver if there is no scene available, i.e. when the
  155. // sound3d object has been removed from the scene
  156. _driver.mute = (_scene == null);
  157. // Force update
  158. update();
  159. // Re-update reference vector to force changes to take effect
  160. _driver.updateReferenceVector(_refv);
  161. }
  162. /**
  163. * @internal
  164. * When scene transform changes, calculate the relative vector between the listener/reference object
  165. * and the position of this sound source, and update the driver to use
  166. * this as the reference vector.
  167. */
  168. private function update():void
  169. {
  170. // Transform sound position into local space of the reference object ("listener").
  171. _refv = _reference.inverseSceneTransform.transformVector(sceneTransform.position);
  172. _driver.updateReferenceVector(_refv);
  173. }
  174. private function onSceneTransformChanged(ev:Object3DEvent):void
  175. {
  176. update();
  177. }
  178. private function onSoundComplete(ev:Event):void
  179. {
  180. dispatchEvent(ev.clone());
  181. }
  182. }
  183. }