Adding Sound Effects to Your Flex/AIR Application

by

It’s easy to add sounds to a Flex/Air application. Here we’ll see how to add whirrs, chirps, and bloops to your application’s button clicks and mouseovers. We’ll also see how to use Air’s EncryptedLocalStore to add mute and volume controls.

The first step is to create a sound manager for playing the sounds. The sound manager will make it possible to centrally apply user preferences like volume to all application sounds.

    import flash.data.EncryptedLocalStore;

    import flash.media.SoundTransform;

    import flash.utils.ByteArray;

    import mx.core.SoundAsset;

    public class SoundManager

    {

        public static const DEFAULT_VOLUME:Number = 3;

        public static function play(sound:SoundAsset):void {

            var sndXfrm:SoundTransform;

            var sndXfrmVal:Number = 0;

            var muteBytes:ByteArray = EncryptedLocalStore.getItem(“muted”);

            var volBytes:ByteArray = EncryptedLocalStore.getItem(“volume”);

            //handle mute condition

            if (muteBytes && muteBytes.readUTFBytes(muteBytes.length) == “true”) {

                //don’t play a sound

                return;

            }

            //handle volume condition (should be a val between 1 and 10)

            if (volBytes) {

                sndXfrmVal = parseInt(volBytes.readUTFBytes(volBytes.length));

                if(sndXfrmVal == 0 || isNaN(sndXfrmVal)) {

                    //couldn’t find a valid value

    //in the ELS (the user has not set prefs yet)

                    sndXfrmVal = DEFAULT_VOLUME;

                }

            } else {

                sndXfrmVal = DEFAULT_VOLUME;

            }

            sndXfrm = new SoundTransform(0.1 * sndXfrmVal);

            sound.play(0, 0, sndXfrm);

        }

    }


The SoundManager takes a SoundAsset as an argument to the play function. This object references an embedded sound file.

Now that we have a sound manager, let’s create a special Button for our application that will play sounds. To do this we’ll extend the flex Button component. Users will hear sound.mp3 when they click the button. We could easily expand this class to play sounds for mouseovers as well.

    import flash.events.MouseEvent;

    import mx.controls.Button;

    import mx.core.SoundAsset;

    public class SoundEffectButton extends Button

    {

        [Embed(source=“assets/sound.mp3”)]

        private var mouseClickSoundClass:Class;

        [Bindable]

        public var mouseClickSound:SoundAsset =

   SoundAsset(new mouseClickSoundClass());

        public function SoundEffectButton()

        {

            super();

        }

        override protected function clickHandler(event:MouseEvent):void {

            super.clickHandler(event);

            SoundManager.play(mouseDownSound);

        }

    }

Now that we have a button, let’s use it! Note that we are overriding the default sound.mp3 referred to in the SoundEffectButton class with a short burst of ACDC rock and roll.

    <mx:Script>

        <![CDATA[

            import mx.controls.Alert;

            import mx.core.SoundAsset;

            [Embed(‘assets/acdc.mp3’)]

            private var acdcClass:Class;

            private var acdc:SoundAsset = SoundAsset(new acdcClass());

        ]]>

    </mx:Script>

    <local:SoundEffectButton label=”Test” mouseClickSound=”{acdc}/>


Finally, we want to salute our esteemed users by giving them the option to not be about to rock out to ACDC. The following code lets users turn down the volume by providing a nifty slider. The SoundManager (remember her?) will now know to turn down the volume. We could also add a couple of radio buttons in order to let the user toggle between mute and unmute states.

As you can see, ELS provides a simple means of communicating user preference changes without the trouble of dealing with controllers and explicit file reads.

    <mx:HSlider id=”volume

            minimum=”1

            maximum=”10

            value=”1

            liveDragging=”true

            showDataTip=”false

            tickInterval=”1

            snapInterval=”1>

        <mx:change>

            <![CDATA[

                var bytes:ByteArray = new ByteArray();

                bytes.writeUTFBytes(volume.value.toString());

                EncryptedLocalStore.setItem(“volume”, bytes);

            ]]>

        </mx:change>

    </mx:HSlider>


1 Comment

Leave a Reply

Your email address will not be published. Required fields are marked *