//////////////////////////////////////////////////////////////////////////////// // // Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to You under the Apache License, Version 2.0 // (the "License"); you may not use this file except in compliance with // the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //////////////////////////////////////////////////////////////////////////////// package mx.effects { import flash.errors.IOError; import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.media.Sound; import flash.media.SoundLoaderContext; import flash.net.URLRequest; import mx.effects.effectClasses.SoundEffectInstance; import mx.managers.ISystemManager; import mx.managers.SystemManager; import mx.resources.IResourceManager; import mx.resources.ResourceManager; /** * Dispatched when the sound file finishes loading. * * @eventType flash.events.Event.COMPLETE * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="complete", type="flash.events.Event")] /** * Dispatched when ID3 data is available for an MP3 sound file. * * @eventType flash.events.Event.ID3 * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="id3", type="flash.events.Event")] /** * Dispatched when an error occurs during the loading of the sound file. * * @eventType flash.events.IOErrorEvent.IO_ERROR * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="ioError", type="flash.events.IOErrorEvent")] /** * Dispatched periodically as the sound file loads. * *

Within the event object, you can access the number of bytes * currently loaded and the total number of bytes to load. * The event is not guaranteed to be dispatched, which means that * the complete event might be dispatched * without any progress events being dispatched.

* * @eventType flash.events.ProgressEvent.PROGRESS * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ [Event(name="progress", type="flash.events.ProgressEvent")] [ResourceBundle("effects")] /** * The SoundEffect class plays an MP3 audio file. * For example, you could play a sound when a user clicks a Button control. * This effect lets you repeat the sound, select the source file, * and control the volume and pan. * *

You specify the MP3 file using the source property. * If you have already embedded the MP3 file, using the Embed * keyword, you can pass the Class object of the MP3 file to the * source property. * Otherwise, specify the full URL to the MP3 file.

* * @mxml * *

The <mx:SoundEffect> tag * inherits all of the tag attributes of its superclass, * and adds the following tag attributes:

* *
 *  <mx:SoundEffect
 *    Properties
 *    id="ID"
 *    autoLoad="true|false"
 *    bufferTime="1000"
 *    loops="0"
 *    panEasingFunction=""
 *    panFrom="0"
 *    source=""
 *    startTime="0"
 *    useDuration="true|false"
 *    volumeEasingFunction="true|false"
 *    volumeTo="1"
 *     
 *    Events
 *    complete="No default"
 *    id3="No default"
 *    ioError="No default"
 *    progress="No default"
 *  />
 *  
* * @see mx.effects.effectClasses.SoundEffectInstance * @see flash.media.Sound * * @includeExample examples/SoundEffectExample.mxml * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public class SoundEffect extends Effect { include "../core/Version.as"; //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @param target The Object to animate with this effect. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function SoundEffect(target:Object = null) { super(target); instanceClass = SoundEffectInstance; } //-------------------------------------------------------------------------- // // Variables // //-------------------------------------------------------------------------- /** * @private */ private var needsLoading:Boolean = false; /** * @private * Used for accessing localized Error messages. */ private var resourceManager:IResourceManager = ResourceManager.getInstance(); //-------------------------------------------------------------------------- // // Properties // //-------------------------------------------------------------------------- //---------------------------------- // autoLoad //---------------------------------- /** * @private * Storage for the autoLoad property. */ private var _autoLoad:Boolean = true; [Inspectable(category="General", defaultValue="true")] /** * If true, load the MP3 file * when the source has been specified. * * @default true * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get autoLoad():Boolean { return _autoLoad; } /** * @private */ public function set autoLoad(value:Boolean):void { _autoLoad = value; } //---------------------------------- // bufferTime //---------------------------------- [Inspectable(category="General", defaultValue="1000")] /** * The SoundEffect class uses an internal Sound object to control * the MP3 file. * This property specifies the minimum number of milliseconds * worth of sound data to hold in the Sound object's buffer. * The Sound object waits until it has at least * this much data before beginning playback, * and before resuming playback after a network stall. * * @default 1000 * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var bufferTime:Number = 1000; //---------------------------------- // isLoading //---------------------------------- /** * This property is true if the MP3 has been loaded. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get isLoading():Boolean { if (_sound) { return _sound.bytesTotal > 0; } return false; } //---------------------------------- // loops //---------------------------------- [Inspectable(category="General", defaultValue="0")] /** * The number of times to play the sound in a loop, where a value of * 0 means play the effect once, a value of 1 means play the effect twice, * and so on. If you repeat the MP3 file, it still uses the setting of the * useDuration property to determine the playback time. * *

The duration property takes precedence * over this property. * If the effect duration is not long enough to play the sound * at least once, the sound does not loop.

* * @default 0 * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var loops:int = 0; //---------------------------------- // panEasingFunction //---------------------------------- /** * The easing function for the pan effect. * Use this function to interpolate between the values * of panFrom and panTo. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var panEasingFunction:Function; //---------------------------------- // panFrom //---------------------------------- [Inspectable(category="General", defaultValue="0.0")] /** * Initial pan of the Sound object. * The value can range from -1.0 to 1.0, where -1.0 uses only the left * channel, 1.0 uses only the right channel, and 0.0 balances the sound * evenly between the two channels. * * @default 0.0 * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var panFrom:Number; //---------------------------------- // panTo //---------------------------------- [Inspectable(category="General", defaultValue="0.0")] /** * Final pan of the Sound object. * The value can range from -1.0 to 1.0, where -1.0 uses only the left channel, * 1.0 uses only the right channel, and 0.0 balances the sound evenly * between the two channels. * * @default 0.0 * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var panTo:Number; //---------------------------------- // sound //---------------------------------- /** * @private */ private var _sound:Sound; /** * The Sound object that the MP3 file has been loaded into. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get sound():Sound { return _sound; } //---------------------------------- // source //---------------------------------- /** * @private * Storage for the source property. */ private var _source:Object; [Inspectable(category="General", defaultValue="null")] /** * The URL or class of the MP3 file to play. * If you have already embedded the MP3 file, using the Embed keyword, * you can pass the Class object of the MP3 file to the source property. * Otherwise, specify the full URL to the MP3 file. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function get source():Object { return _source; } /** * @private */ public function set source(value:Object):void { if (_sound) { try { _sound.close(); } catch(e:IOError) { // Ignore these } removeSoundListeners(); } _source = value; if (_source is Class) { var cls:Class = Class(_source); _sound = new cls(); attachSoundListeners(); } else if (_source is String) { needsLoading = true; _sound = new Sound(); attachSoundListeners(); } else { var message:String = resourceManager.getString( "effects", "incorrectSource"); throw new Error(message); } if (autoLoad) load(); } //---------------------------------- // startTime //---------------------------------- [Inspectable(category="General", defaultValue="0")] /** * The initial position in the MP3 file, in milliseconds, * at which playback should start. * * @default 0 * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var startTime:Number = 0; //---------------------------------- // useDuration //---------------------------------- [Inspectable(category="General", defaultValue="true")] /** * If true, stop the effect * after the time specified by the duration * property has elapsed. * If false, stop the effect * after the MP3 finishes playing or looping. * * @default true * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var useDuration:Boolean = true; //---------------------------------- // volumeEasingFunction //---------------------------------- /** * The easing function for the volume effect. * This function is used to interpolate between the values * of volumeFrom and volumeTo. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var volumeEasingFunction:Function; //---------------------------------- // volumeFrom //---------------------------------- [Inspectable(category="General", defaultValue="1.0")] /** * Initial volume of the Sound object. * Value can range from 0.0 to 1.0. * * @default 1 * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var volumeFrom:Number; //---------------------------------- // volumeTo //---------------------------------- [Inspectable(category="General", defaultValue="1.0")] /** * Final volume of the Sound object. * Value can range from 0.0 to 1.0. * * @default 1 * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var volumeTo:Number; //-------------------------------------------------------------------------- // // Overridden methods // //-------------------------------------------------------------------------- /** * @private */ override protected function initInstance(instance:IEffectInstance):void { super.initInstance(instance); var soundEffectInstance:SoundEffectInstance = SoundEffectInstance(instance); soundEffectInstance.source = source; soundEffectInstance.sound = sound; soundEffectInstance.panFrom = panFrom; soundEffectInstance.panTo = panTo; soundEffectInstance.volumeFrom = volumeFrom; soundEffectInstance.volumeTo = volumeTo; soundEffectInstance.panEasingFunction = panEasingFunction; soundEffectInstance.volumeEasingFunction = volumeEasingFunction; soundEffectInstance.loops = loops; soundEffectInstance.startTime = startTime; soundEffectInstance.useDuration = useDuration; } //-------------------------------------------------------------------------- // // Methods // //-------------------------------------------------------------------------- /** * Loads the MP3 if the source property points to a URL. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function load():void { if (_sound && _source && _source is String && needsLoading) _sound.load(new URLRequest(String(_source)), new SoundLoaderContext(bufferTime)); } /** * @private */ private function attachSoundListeners():void { if (_sound) { _sound.addEventListener(Event.COMPLETE, soundEventHandler); _sound.addEventListener(ProgressEvent.PROGRESS, soundEventHandler); _sound.addEventListener(IOErrorEvent.IO_ERROR, soundEventHandler); _sound.addEventListener(Event.ID3, soundEventHandler); } } /** * @private */ private function removeSoundListeners():void { if (_sound) { _sound.removeEventListener(Event.COMPLETE, soundEventHandler); _sound.removeEventListener(ProgressEvent.PROGRESS, soundEventHandler); _sound.removeEventListener(IOErrorEvent.IO_ERROR, soundEventHandler); _sound.removeEventListener(Event.ID3, soundEventHandler); } } //-------------------------------------------------------------------------- // // Event handlers // //-------------------------------------------------------------------------- /** * Just act as a proxy for all events from the sound. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ private function soundEventHandler(event:Event):void { dispatchEvent(event); } } }