Thursday, November 29, 2007

Controlling sound in Flash CS 3 or ActionScript 3.0

I was trying to make an audio player for a web site in flash cs 3 or actionscript 3.0 today and it was more than confusing..

i was reading the references and took me a while before i realized that you had to have bunch of other objects to perform tasks like stopping,..

yes.. stopping sound seems easy but not really in actionscript 3.0..but once you get it you won't forget it.

to make an audio or mp3 player in as3 you need three objects.

Sound() - for loading sounds
SoundChannel() - to control playback, stopping
SoundTransform() - to control volume and panning(Left, right stereo stuff)

SoundChannel has .soundTransfor where you can assign SoundTransform() object


var sound:Sound = new Sound();
var sControl:SoundChannel = new SoundChannel();
var vControl:SoundTransform = new SoundTransform();


so now you have 3 objects. let take a look at how they interrelate


sound.load(new URLRequest("yourSong.mp3"); // get the sound clip
sound.addEventListener(Event.COMPLETE, soundLoaded); // triggers a function soundLoaded on load complete
btnStop.addEventListener(MouseEvent.CLICK, stopSound); // create button with inst name of btnStop on stage for it to work
btnVolumeUp.addEventListener(MouseEvent.CLICK, changeVolume);

function soundLoaded(e:Event):void
{
sControl = sound.play(); // this is the hard part...
}

function stopSound(e:MouseEvent):void
{
sControl.stop(); // sound.stop() won't work for some reason.. or for a good reason..
}

function changeVolume(e:MouseEvent):void
{
vControl.volume += .1; // since volume property's range is 0 to 1
sControl.soundTransform = vControl; // assign that info to control
}


well this should blow up your speaker since it only goes up. try it at your own risk and i didn't tell you to do it. so you can't sue me. you should spend your time in other things like try implementing decreasing volume or much more flexible way of controling volume, etc.

9 comments:

terraform said...

Hey thanks for explaining
I have melded my code with your example
and I am having a conflict (which existed before I used some of your code)
and was wondering if you had any thoughts on why?

Sound is really driving me nuts
and all I need it to do is play and pause the background music.

I have one button that plays and pauses the audio
(well 2 buttons which trade visibility depending on button click)
all I need is the sound to load (buffered streaming would be nice) then play the background loop
and allow the user to pause when they want.
simple right...
Hrmph...

this is where I am at now

var sound:Sound = new Sound();
var sControl:SoundChannel = new SoundChannel();
var vControl:SoundTransform = new SoundTransform();
var lastPosition:Number = 0; //***



sound.load(new URLRequest("Sound.mp3")); // get the sound clip
sound.addEventListener(Event.COMPLETE, soundLoaded); // triggers a function soundLoaded on load complete


play_btn.addEventListener(MouseEvent.CLICK,playF);
stop_btn.addEventListener(MouseEvent.CLICK,stopF);
play_btn.visible = false;

function soundLoaded(e:Event):void
{
sControl = sound.play();
}

function playF(e:MouseEvent):void
{
sControl = sound.play(lastPosition, 100, new SoundTransform(0.7));

play_btn.visible = false;
stop_btn.visible = true;
}


function stopF(e:MouseEvent):void
{
SoundMixer.stopAll();
lastPosition = sControl.position;
sControl.stop();

play_btn.visible = true;
stop_btn.visible = false;
}

SONARHYTHM Logic Pro School said...

What exactly is the problem you are having?

Are you getting any error message?

I've tested your code on my own and it seems to be working fine..

terraform said...

sorry I forgot to mention that

I am having some sort of a conflict
where on multiple button clicks the functionality
disintegrates in one way or another
either the entire thing freezes or it starts a stutter
pattern that in turn leads to freezing.

the way that I originally had it
I did not have the entire clip load
but instead had it buffer for 3 seconds

and I had thought that that was causing the conflict.

now I am not sure.

ps
thanks for your quick reply and looking at the code
:-)

SONARHYTHM Logic Pro School said...

actually... found one problem.

you are playing from lastPosition even when you are repeating.

Maybe just add another event listener

SoundChannelObj.addEventListener(Event.SOUND_COPMPLETE, functionname);
and declare function and reset the value of lastPosition

SONARHYTHM Logic Pro School said...

you could just disable?? perhaps?

buttonObj.enabled = true or false

SONARHYTHM Logic Pro School said...

var sound:Sound = new Sound();
var sControl:SoundChannel = new SoundChannel();
var vControl:SoundTransform = new SoundTransform(0.7);
var lastPosition:Number = 0; //***


sound.load(new URLRequest("SOUDNDCLIP.mp3")); // get the sound clip
sound.addEventListener(Event.COMPLETE, soundLoaded); // triggers a function soundLoaded on load complete

play_btn.addEventListener(MouseEvent.CLICK,playF);
stop_btn.addEventListener(MouseEvent.CLICK,stopF);

play_btn.visible = false;

function soundLoaded(e:Event):void
{
sControl = sound.play(0, 0, vControl);
sControl.addEventListener(Event.SOUND_COMPLETE, onSoundComp);
lastPosition = sControl.position;
}

function playF(e:MouseEvent):void
{
sControl = sound.play(lastPosition, 0);
sControl.addEventListener(Event.SOUND_COMPLETE, onSoundComp);

play_btn.visible = false;
stop_btn.visible = true;
}

function stopF(e:MouseEvent):void
{
lastPosition = sControl.position;
SoundMixer.stopAll();

play_btn.visible = true;
stop_btn.visible = false;
}

function onSoundComp(e:Event) {
sControl = sound.play(0, 0, vControl);
sControl.addEventListener(Event.SOUND_COMPLETE, onSoundComp);

}

terraform said...

WoW
that was perfect.
Thank you so much.
you have no idea how much that helps me.

I will pick it apart and try to learn from it.

again thank you!!!

SONARHYTHM Logic Pro School said...

cool I don't know what made it work but great!

It was like a good brain teaser for me since i couldn't sleep and i was trying to look for something..

points:

vControl declaration - (0.7) instead of ()

play button and play()
by doing
SCobj = sound.play()
it resets What's in soundChannel obj so you had to do things every time.
so i've added my sound complete event listener as well.


this is prob optional but i've removed one extra stop function (there were two of them: SMixer.stopAll and SCh.stop )

lastPosition = sControl.position;
comes before stopping the sound.

i think those 4 points are something i've changed.

terraform said...

not sure which one it was either
but I am super psyched that it is working.

thanks again.

s