PageRenderTime 234ms CodeModel.GetById 111ms app.highlight 7ms RepoModel.GetById 113ms app.codeStats 0ms

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