Wednesday, January 20, 2010

Flash AS3 Volume Control Tutorial

Exercise Files:
Adjusting_Volume_Start.fla
CheerfulSong.mp3

NOTE: Be sure to save both files in the same folder.

To adjust sound volume in Flash, you will need a SoundTransform object. The SoundTransform class has a volume property, which you can assign a value from 0 - 1. Where 0 is mute, and 1 is full volume.

For example:
var volumeAdjust:SoundTransform = new SoundTransform();
volumeAdjust.volume = .5;
The first line creates a SoundTransform object named volumeAdjust. The next line sets the volume property to .5.

But this doesn't adjust the volume of the sound just yet. Yes, we've set a new volume level, but we still haven't applied it to any sound. So after creating the SoundTransform object and setting the volume level, we must then apply the SoundTransform object to a specific SoundChannel. You can do this using the soundTransform property of the SoundChannel class.

NOTE: Be aware of the distinction between a SoundTransform object (which would be an instance of the SoundTransform class) and the soundTransform property (which is a property of the SoundChannel class). A SoundTransform object is what holds the value for the volume level adjustment, where as the soundTransform property of the SoundChannel class is used in order to apply that volume level adjustment to the sound. Also notice that the soundTransform property starts with a lowercase s, while the SoundTransform class starts with an uppercase S.

Example:
// Assume that channel1 is a SoundChannel object and that there is
// already a sound assigned to that channel
channel1.soundTransform = volumeAdjust;
This statement assigns the SoundTransform object named volumeAdjust, to the soundTransform property of the SoundChannel object named channel1. So this means that whatever sound is being played on that SoundChannel will have the volume adjustment applied to it.

NOTE: The volume property can actually accept values that are greater than 1, as well as negative values. But generally, you should only allow values between 0 - 1 (nothing greater nothing less) because values outside that range can end up distorting the sound. Negative values will actually increase the volume as well. So if the volume property has a value that goes below 0, the sound volume comes back up. You can use an if statement with an else clause in order to set constraints (which we will do later on).

So let's begin.

Open the exercise file and select the first frame of the Actions layer. In the Actions Panel, you'll see that there's already some code:
var mySound:Sound = new Sound();
var songURL:URLRequest = new URLRequest("CheerfulSong.mp3");
var channel1:SoundChannel = new SoundChannel();

mySound.load(songURL);

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

function playSound(e:MouseEvent):void 
{
     channel1 = mySound.play();
}

function stopSound(e:MouseEvent):void 
{
     channel1.stop();
}
This code just loads the sound and creates the playing and stopping functionality. We will just be adding the volume controls.

On the stage, you will see two small buttons: one pointing up (volUp_btn) and one pointing down (volDown_btn). These buttons will be made clickable in order to adjust the volume.

But first, let's go ahead an create the SoundTransform object. I will name it volumeAdjust:
var mySound:Sound = new Sound();
var songURL:URLRequest = new URLRequest("CheerfulSong.mp3");
var channel1:SoundChannel = new SoundChannel();
var volumeAdjust:SoundTransform = new SoundTransform();

mySound.load(songURL);

Next, let's go ahead and create the event handlers for the volume buttons. I will name the listener functions volUp (for increasing the volume) and volDown (for decreasing the volume):
play_btn.addEventListener(MouseEvent.CLICK, playSound);
stop_btn.addEventListener(MouseEvent.CLICK, stopSound);
volUp_btn.addEventListener(MouseEvent.CLICK, volUp);
volDown_btn.addEventListener(MouseEvent.CLICK, volDown);

function playSound(e:MouseEvent):void
{
     channel1 = mySound.play();
}

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

function volUp(e:MouseEvent):void 
{
     //code to increase the volume goes here
}

function volDown(e:MouseEvent):void 
{
     //code to decrease the volume goes here
}

Next, let's set the initial volume.

Set the volume property of the SoundTransform object to the desired level. I will give it a value of .5:
var mySound:Sound = new Sound();
var songURL:URLRequest = new URLRequest("CheerfulSong.mp3");
var channel1:SoundChannel = new SoundChannel();
var volumeAdjust:SoundTransform = new SoundTransform();

volumeAdjust.volume = .5;
Then go to the playSound function (that's the listener function that's called whenever the play button is clicked) and add the following line (highlighted in bold):
function playSound(e:MouseEvent):void 
{
     channel1 = mySound.play();
     channel1.soundTransform = volumeAdjust;
}
Code explained:
volumeAdjust.volume = .5;
This line sets the volume property of the SoundTransform object to .5 (which is at half the full volume level).

channel1.soundTransform = volumeAdjust;
Then to apply the change in volume, the volumeAdjust SoundTransform object is assigned to the soundTransform property of channel1. It's important to note that this line must be added after the play sound statement is assigned to the SoundChannel object. Otherwise, the volume change will not be applied.

So now, we've set the initial volume to .5. Test the movie and try applying different volume levels in order to hear the difference. Try putting in a value greater than 1 (around 15-20, for example) and you will notice some sound distortion (be sure to keep your ears a comfortable distance away from the sound source when you do this). Then make sure you bring it back down to .5 when you continue the tutorial.

After setting the initial volume, let's now start working on the buttons for adjusting the volume.

To increase the volume, we can simply increment the value of the SoundTransform object's volume property whenever the volume up button is clicked. Go to the volUp listener function and add the following lines highlighted in bold:
function volUp(e:MouseEvent):void 
{
     volumeAdjust.volume += .1;
     channel1.soundTransform = volumeAdjust;
}

Code explained:
volumeAdjust.volume += .1;
This line increments the current volume property value by .1. So every time the volume up button is clicked, the volume property's value increases by .1.

channel1.soundTransform = volumeAdjust;
Every time changes are made to the volume property of the SoundTransform object, it must be reapplied to the SoundChannel's soundTransform property in order for the changes to take effect. So you have to make sure that you add this line as well.

But wait! Early on, I mentioned that continuously increasing the volume way above a value of 1 will end up distorting the sound. So we'll need to limit the volume adjustment to a range of just 0 to 1. In order to do that, we can use if statements.

Go back to the volUp function and add the following (highlighted in bold):
function volUp(e:MouseEvent):void 
{
     volumeAdjust.volume += .1;
     if(volumeAdjust.volume > 1)
     {
          volumeAdjust.volume = 1;
     } 
     channel1.soundTransform = volumeAdjust;
}
Code explained:
So whenever the volume up button is clicked, the volume property is incremented first. Then before the volume adjustment is applied using the soundTransform property, the if statement checks whether the new volume value has gone over 1. If it has, then the volume property value is immediately brought back down to 1, before the volume adjustment is applied. This effectively limits the maximum volume to 1 no matter how many times the volume button is pressed.

And lastly, for decreasing the volume, we use the same concept. Except for this one, we would like to DECREMENT the value of the volume property instead. And for the if statement, we would like to check whether the volume property's value is LESS THAN 0. Whenever it goes below 0, then we want to immediately pull it back up again to 0. So that way, we effectively limit the minimum volume to 0. So go to the volDown function and add the following lines highlighted in bold:
function volDown(e:MouseEvent):void 
{
     volumeAdjust.volume -= .1;
     if(volumeAdjust.volume < 0)
     {
          volumeAdjust.volume = 0;
     } 
     channel1.soundTransform = volumeAdjust;
}
So there you have it. You've just created simple volume controls in ActionScript 3.0.

Here's the code in full:
var mySound:Sound = new Sound();
var songURL:URLRequest = new URLRequest("CheerfulSong.mp3");
var channel1:SoundChannel = new SoundChannel();
var volumeAdjust:SoundTransform = new SoundTransform();

volumeAdjust.volume = .5;

mySound.load(songURL);

play_btn.addEventListener(MouseEvent.CLICK, playSound);
stop_btn.addEventListener(MouseEvent.CLICK, stopSound);
volUp_btn.addEventListener(MouseEvent.CLICK, volUp);
volDown_btn.addEventListener(MouseEvent.CLICK, volDown);

function playSound(e:MouseEvent):void 
{
  channel1 = mySound.play();
  channel1.soundTransform = volumeAdjust;
}

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

function volUp(e:MouseEvent):void 
{
  volumeAdjust.volume += .1;
  if(volumeAdjust.volume > 1)
  {
    volumeAdjust.volume = 1;
  } 
  channel1.soundTransform = volumeAdjust;
}

function volDown(e:MouseEvent):void 
{
  volumeAdjust.volume -= .1;
  if(volumeAdjust.volume < 0) 
  {
    volumeAdjust.volume = 0;
  } 
  channel1.soundTransform = volumeAdjust;
}

15 comments:

  1. Fantastic tutorial for beginners you really helped me out, Thanks alot!

    ReplyDelete
  2. You're welcome! :) If you have the time, please do share it with your friends, too!

    ReplyDelete
  3. just tried to open the demo FLA in flash CS3 and got an error - is it a CS4 file?
    -mike

    ReplyDelete
  4. Yes it's a CS4 file. To recreate the demo file, just put 4 button instances on the stage with the ff instance names: play_btn, stop_btn, volUp_btn and volDown_btn

    ReplyDelete
  5. I must agree with all the positive remarks. Excellent tutorial!

    I have one question. When I follow the tutorial I basicly get a player with four buttons (well that is the idea, isn't it? :) ). I click play in order to play the sound. My question is how to alter the code if I wish the sound to start automaticly from the beginning.

    This is for a website, you know. When the visitor enters the main page the music starts automaticly. Then, the visitor has the choice to decrease the volume or stop and then again start the sound clip.

    Could you gice med any advice?

    ReplyDelete
  6. Hi, Pelaseyed.

    Thanks for visiting the site. If you want the sound to play right away, you can just place a copy of these lines outside the playSound function:

    channel1 = mySound.play();
    channel1.soundTransform = volumeAdjust;

    You can place that right after mySound.load(songURL)

    Since you have those lines outside of the playSound event listenter function (which only executes when a user clicks on the play button), then the song will start playing right away as long as enough of it has been downloaded.

    Hope this helps!

    ReplyDelete
  7. Hi,
    I just downloaded the source files - didn't change a thing in them - but the volume adjustment is not working. The song plays, the play & stop buttons work, but both the volume up & down buttons do nothing! Any ideas?

    ReplyDelete
  8. did you copy and paste the code or did you type it? could be a typo somewhere.

    ReplyDelete
  9. Hi, The volDown tends to bring the volume to 0 and the volUp increases the volume only gradually. Any tips?

    ReplyDelete
  10. You can just change the value used to increment or decrement the volume. If you want more abrupt changes, try incremementing or decrementing by .25 instead of just .1

    ReplyDelete
  11. Great tutorial. Thank you very much.

    ReplyDelete
  12. Hello friend! Congratulations for your fantastic site! Is it possible to embed mp3 file in as3 code?

    ReplyDelete
  13. This is great tutorial for basic learners. I'm developing application in Air for Mobile device. I want to control my app volume when user doing action with mobile volume hardware keys. How do I detect volumeUp and volumeDown hardware key is pressed?

    ReplyDelete
  14. God Bless you men for sharing this great tut. Very understandable

    ReplyDelete
  15. Hello How can I use value (volumeAdjust) as conversion, for example, trace

    ReplyDelete