Easy sound control in AS3

Yes, it’s possible!

To give Adobe their due credit, the new sound system in AS3 does make a lot of sense from an OO programming standpoint. However, what about basic usability? There’s no two ways about it: the new design pattern takes some serious head-scratching to assemble all the pieces of API; as in: you need to play the sound to get the sound channel to stop the sound or to listen for the complete event… you know the drill.

So, I recently got fed up and finally just built a definitive wrapper for sound objects that would take care of ALL the nuances of sound playback, making them simple to control. This includes some crazy features like the ability to pause and resume a looping sound (can you say “background music”?), or the ability to toggle a sound in and out of a loop. So, just instance the class below with a Sound object in its constructor, and this wrapper will provide an extremely simple API to control the sound with.

UPDATE: This post has evolved into SoundSkin, an ActionScript 3 library for easy sound management. I’ve set up an official project page on Google code at: http://code.google.com/p/sound-skin/. See the download page for source code and full documentation. I am posting updates and extentions as I create them.

Advertisements

8 comments so far

  1. […] new sound library is available, very useful for game development among others, called SoundSkin. Thanks Greg. May Open Source live […]

  2. Craig on

    Hi,

    AS3 newbie here, using soundSkin in a “start/stop” control for a web site background music. How do you add an event listener so it triggers when the sound loop comes to it’s natural end. I’ve tried $sound.addEventListener(Event.SOUND_COMPLETE,_setButtonStop); but it doesn’t fire.

    Sorry if this is really basic stuff but I’m not a Flash developer, just doing a job on a web site.

    Any help appreciated.

    Craig

    • bigmac on

      SoundSkin dispatches native event types to match its custom event model. SoundSkin tracks two different completion events, they would be subscribed as:

      $soundSkin.addEventListener(SoundSkin.SOUND_LOOP, _onLoop);
      $soundSkin.addEventListener(SoundSkin.SOUND_COMPLETE, _onAllLoopsComplete);

      SOUND_LOOP is called each time the source sound completes playback of a track loop. Given that SoundSkin has built-in looping, this event is called as many times as the track is set to loop.

      SOUND_COMPLETE is called after all track loops have finished playing. If the track is not configured to loop, then this would be called at the end of a single sound playback, just the way a Flash native sound playback event would be called.

      • ardian on

        The following code taken from a sample file Soundskin. What and Where I must enter the code so that the sound (flyingoverthesun.mp3) play continues / loop?


        import com.gmac.sound.SoundSkin;

        var $sound:SoundSkin = new SoundSkin();
        $sound.load("flyingoverthesun.mp3", true);

        // playback button
        playbackBttn.stop();
        playbackBttn.addEventListener(MouseEvent.CLICK, this._onPlay);
        playbackBttn.buttonMode = true;
        playbackBttn.useHandCursor = true;

        // mute button
        muteBttn.stop();
        muteBttn.addEventListener(MouseEvent.CLICK, this._onMute);
        muteBttn.buttonMode = true;
        muteBttn.useHandCursor = true;

        // scrubber controls
        addEventListener(Event.ENTER_FRAME, this._onShowStatus);
        var _scrubTarget:MovieClip;
        var _progressMax:Number = progressBar.width;
        var _volumeMax:Number = volumeBar.width;

        // progress display / scrub
        progressScrub.addEventListener(MouseEvent.MOUSE_DOWN, this._onScrubPress);
        progressScrub.buttonMode = true;
        progressScrub.useHandCursor = true;
        progressBar.mouseEnabled = false;

        // volume display / scrub
        volumeScrub.addEventListener(MouseEvent.MOUSE_DOWN, this._onScrubPress);
        volumeScrub.buttonMode = true;
        volumeScrub.useHandCursor = true;
        volumeBar.mouseEnabled = false;

        // Event handlers

        function _onPlay($event:Event):void {
        $sound.togglePlayback();
        playbackBttn.gotoAndStop($sound.playing ? 2 : 1);
        }

        function _onMute($event:Event):void {
        $sound.toggleMute();
        muteBttn.gotoAndStop($sound.mute ? 2 : 1);
        }

        function _onShowStatus($event:Event):void {
        progressBar.width = _progressMax * $sound.percentPlayback;
        volumeBar.width = _volumeMax * $sound.volume;
        }

        function _onScrubPress($event:Event):void {
        _scrubTarget = $event.target as MovieClip;
        stage.addEventListener(MouseEvent.MOUSE_UP, this._onScrubRelease);
        stage.addEventListener(MouseEvent.MOUSE_MOVE, this._onScrub);
        scrub();
        }

        function _onScrubRelease($event:Event):void {
        stage.removeEventListener(MouseEvent.MOUSE_UP, this._onScrubRelease);
        stage.removeEventListener(MouseEvent.MOUSE_MOVE, this._onScrub);
        }

        function _onScrub($event:Event):void {
        scrub();
        }

        function scrub():void {
        var $percent:Number = (mouseX - _scrubTarget.x) / _scrubTarget.width;
        $percent = Math.max(0, Math.min($percent, 1));

        if (_scrubTarget == progressScrub) {
        $sound.percentPlayback = $percent;
        }
        else if (_scrubTarget == volumeScrub) {
        $sound.volume = $percent;
        }
        }

  3. Dan Zen on

    Thanks Greg – always wanted to make one of these – hmm… I think I did at one time – or at least cross faders. If you get the chance or have the inclination, check out the Flash Feathers series of advanced interfaces – you may find something useful. http://flashfeathers.com

  4. dan on

    Can your sound wrapper mute all sound effects in a game at once?

    • bigmac on

      For this, you’d use Flash’s native sound methods. I seem to recall that the command you’re after is ChannelMixer.stopAllSounds();

  5. Ram on

    Thanks a lot for this..


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: