7-day free trial

Monday, January 17, 2011

AS3 - Play Sound from Library

lynda.com online training tutorials
Exercise File:
claps.wmv

*Sound loop created by Brad Sucks.

In this tutorial, we're going to learn how to use ActionScript 3 in order to control audio files imported into our Flash document's library. This lesson comes with an audio file, which you can download from the link above. The file is named claps.wav, which is a short 4-second sound file that can be used as a sound loop. We'll also learn how to loop a sound clip's playback in AS3 using the Event.SOUND_COMPLETE event associated with the SoundChannel class.

NOTE: WAV files are ideal for sound loops, while MP3 files are NOT. MP3 files are NOT ideal for sound loops because MP3 audio files have a brief moment at the end where there is no sound. So if you loop an MP3 file, you will have these short silent gaps in between each loop that makes the loop sound as if it's skipping.

Step 1

Let's start by creating a new Flash ActionScript 3 Document.

Step 2

On the stage, let's draw 2 buttons - a play button and a stop button. Let's give them the instance names play_btn and stop_btn respectively. You can give a button an instance name by selecting it, and then going to the Properties Inspector where you will find an input field for the instance name.

Step 3

Once you have the buttons, let's go ahead and import the claps.wmv audio file into the Flash document's library. From the main menu, choose File > Import > Import to Library. Navigate to where the claps.wmv file is in your computer and import the file. When importing is done, you should see the audio file in the Flash document's library.

Step 4

At this point, let's set up the sound file in our library so that we will be able to access it using ActionScript. To do that, right-click on the sound file in the library and choose Properties from the context menu that pops up.

When the Sound Properties dialog box comes up, go to the part that says Linkage. If you don't see this area, click on the Advanced button at the bottom of the dialog box. Once you see the Linkage options, make sure that the following are checked:
  • Export for ActionScript
  • Export in frame 1
This will ensure that our audio file will be exported for ActionScript so that we can control it using our script. Export in frame 1 means that the audio file will be exported to frame 1. That way, the sound file will be available to us from the very beginning of the Flash movie. But this does not mean that the sound will play immediately. It simply means that it's available to us starting at the very first frame if we wish to use it.

Step 5

After we've checked those options, you'll see a couple of input fields become accessible right below the check boxes. Go to the Class input field and change the name to Claps. This allows us to create a class from our audio file. We will use this class in order to create an instance of our claps.wmv sound file, so make sure you remember this name (Claps) because we will use it later on.

NOTE: This class name is author defined. You can give it any name you want as long as it does not conflict with other class names in your project. The class name is case-sensitive.

Step 6

Double-check to see if you've set everything up properly and then click on OK. You will then get a message that says: A definition for this class could not be found in the classpath, so one will be automatically generated in the SWF file upon export. Click on OK so that the Claps class will be generated once you export your SWF.

Now that the sound file in our library is properly set up for use with ActionScript, let's go ahead and write some code.

Step 7

Create a new layer for the Actions, select the first keyframe of that layer, and launch the Actions Panel.

Step 8

Let's go ahead and create an instance of the claps.wmv sound. Remember that the class name we specified is Claps. So type the following line in the script pane:
var clapsSound:Claps = new Claps();
Here, we've created a new instance of the Claps class, which is the class of the sound file in our library. We've named this instance clapsSound. When we play this, it's going to play an instance of the claps.wmv file, which is the sound file from our library that we linked to the Claps class.

Step 9

Next, let's create mouse click event listeners for our play (play_btn) and stop (stop_btn) buttons:
var clapsSound:Claps = new Claps();

play_btn.addEventListener(MouseEvent.CLICK, playSound);
stop_btn.addEventListener(MouseEvent.CLICK, stopSound)

function playSound(e:MouseEvent):void
{

}

function stopSound(e:MouseEvent):void
{

}
Here, we've created 2 event listener functions - playSound for playing the sound, and stopSound for stopping the sound.

Step 10

Inside the playSound event listener function, let's use the play() method of the Sound class in order to instruct the sound to start playing once the button is clicked:
function playSound(e:MouseEvent):void
{
     clapsSound.play();
}
So now, if you test the movie, clicking on the play button will start playing the sound.

Step 11

For stopping the sound, we'll need to create a SoundChannel object first. And then we'll need to assign the play sound statement to that SoundChannel. And then to stop the sound, we'll use the stop() method of the SoundChannel class:
var clapsSound:Claps = new Claps();
var clapsChannel:SoundChannel = new SoundChannel();

play_btn.addEventListener(MouseEvent.CLICK, playSound);
stop_btn.addEventListener(MouseEvent.CLICK, stopSound)

function playSound(e:MouseEvent):void
{
     clapsChannel = clapsSound.play();
}

function stopSound(e:MouseEvent):void
{
     clapsChannel.stop();     
}
So if we test the movie at this point, we can now successfully play and stop our library sound.

In the next part of this article, we'll learn how to make the sound clip loop.

Making a Sound Clip Loop in AS3

If we want to make the sound loop, we'll need to find a way to be able to tell it to play again once the sound has completed the playback (i.e. when it reaches the end). We can use the SoundChannel class to achieve this. The SoundChannel class has an event called Event.SOUND_COMPLETE. This event gets dispatched whenever a sound that's playing in a SoundChannel has completed playback. So we can create an event listener for this event, and then tell the sound to play again once this event gets dispatched (i.e. tell the sound to repeat when it reaches the end).

Let's go ahead and create the event listener function first. Let's name it loopSound. Inside this listener function, we'll instruct the sound to play again. So we'll need to add another play sound statement inside this function:
function playSound(e:MouseEvent):void
{
     clapsChannel = clapsSound.play();
}

function stopSound(e:MouseEvent):void
{
     clapsChannel.stop();
}

function loopSound(e:Event):void
{
     clapsChannel = clapsSound.play();
     trace("The sound has reached the end");
}
I've added in a trace statement so that we will get a message from the Output window once the sound has reached the end. So, now that we've created this listener function, let's go ahead and register it to our SoundChannel object (clapsChannel).

If you're registering an event listener function to the Event.SOUND_COMPLETE event of the SoundChannel class, you must add the event listener only AFTER the sound has been assigned to the SoundChannel (i.e. it must be added after the SoundChannel = Sound.play(); statement). In our exampe, the first time the sound plays will be when we click on the play button. So we must add the Event.SOUND_COMPLETE statement after the play sound statement inside the playSound() function:
function playSound(e:MouseEvent):void
{
     clapsChannel = clapsSound.play();
     clapsChannel.addEventListener(Event.SOUND_COMPLETE, loopSound);
}
If we added this BEFORE the statement that plays the sound and assigns it to the SoundChannel, then the listener will not work the way we want it to.

So now, go ahead and test your movie. When you click on the play button, the sound will start playing. And then when it reaches the end, you will see a message from the Output window (from our trace statement), and the sound will immediately play again.

After you've tested the movie and played the sound, you will notice that the sound will only repeat ONCE. After the second time it plays, it will no longer repeat itself. So here, you will realize that the Event.SOUND_COMPLETE listener will only listen out for the event one time. It's not going to keep listening out for Event.SOUND_COMPLETE indefinitely.

But what if we want it to listen out for Event.SOUND_COMPLETE indefinitely so that we can make our sound loop indefinitely as well?
In order to do that, we'll need to add the event listener AGAIN after it begins playing another time. So we'll need to add the Event.SOUND_COMPLETE listener inside the loopSound() function as well:
function loopSound(e:Event):void
{
     clapsChannel = clapsSound.play();
     clapsChannel.addEventListener(Event.SOUND_COMPLETE, loopSound);
}
So now, we have the add event listener statement for the Event.SOUND_COMPLETE listener in both the playSound() and loopSound() functions right after the clapsChannel = clapsSound.play(); statement. That way, each time the sound plays, Flash will watch out for when the sound completes the playback and will play the sound again. So what we have is a sound clip that will keep repeating indefinitely.

NOTE: If you want more than one sound clip to loop simultaneously using this method, then you'll have to create one SoundChannel for each sound.

And that concludes this tutorial on how to play sound from the library using AS3 and AS3 sound looping

15 comments:

  1. Thanks for the tutorial. I was trying to figure out how to exectue a fuction after sound has finished playing in my flash video. I used your example "clapsChannel.addEventListener(Event.SOUND_COMPLETE, loopSound);" and then in the funtion loopSound, I added the rest of my action codes. Worked Perfectly.

    ReplyDelete
  2. You're welcome! Glad this helped you out. If you could give us a like on facebook that would be great! Have a nice day! :)

    ReplyDelete
  3. How do I call the function? I called loopSound() and it says I need 1 argument. It makes sense, but I don't know what argument to give it.
    Thanks

    ReplyDelete
  4. The argument is the event object. Since loopSound is an event listener, it gets called after the event is dispatched (SOUND_COMPLETE in this case).

    ReplyDelete
  5. i get some latency and i already checked my audiofile??? please help

    ReplyDelete
  6. Try making sure that your audio file's sampling rate is at least 41kHz

    ReplyDelete
  7. Thx! I've been struggling with this in Flash for weeks now and this makes it clearer to me.

    ReplyDelete
  8. I have 4 sounds I want to play. The first works beautifully but the others don't. Each has their own instance, and own buttons, but I have dead stop/play buttons.

    ReplyDelete
  9. Thanks a lot..Your solution helps me...

    ReplyDelete
  10. Thanks a lot...you solved my issue related to loop...

    ReplyDelete
  11. I have a very short (.005 seconds) WAV file (44.1 kHz) that is a single wave cycle of a bee's buzz. I want to loop this WAV file seamlessly to create a buzzing bee sound that I can adjust the pitch, volume, and pan of. The loop I get using this code doesn't cycle quickly enough to make it sound like a buzz. I am afraid that if I use a longer WAV file, the changes will be choppy. Any suggestions?

    ReplyDelete
  12. Why on earth would anyone do sound looping this way when AS3 has it built in already?!

    yourSoundName.play(StartTime,#loops)

    ReplyDelete
    Replies
    1. The loops parameter of the Sound.play() method allows you to define a specific number of times for the sound to loop. But if you don't have a specific number in mind, and just want the sound clip to loop indefinitely, then you can use the SOUND_COMPLETE event handler as demonstrated in the example. But really, the main thing I want readers of this tutorial to learn from that part of this tutorial is that there is a SOUND_COMPLETE event that they can use for a variety of different things in their projects. So think of this more as an example for learning.

      Delete
  13. how do one play the sound once only!! if you see when you click again on the play button it repeats the sound again n so on how do you play it once only. any suggestion

    ReplyDelete