AS3 play sounds in an array in a sequence - actionscript-3

This is being programmed in Flash CS5.5:
I want to push a button, and play through the entire array one sound at a time. When the first sound stops, the second begins, etc. all the way until the last sound plays. When the last sound finishes, all sound should stop, and if you push the play button again, it should start over at the beginning, and play through all sounds again.
Currently, to advance to the next sound, you have to push the button again. I'm thinking the SOUND_COMPLETE needs to be used... I'm just not sure how, hence the empty function. I only want to have to push play one time to hear the entire array in a sequence. Any ideas?
var count;
var songList:Array = new Array("test1.mp3","test2.mp3","test3.mp3");
count = songList.length;
myTI.text = count;
var currentSongId:Number = 0;
playBtn.addEventListener(MouseEvent.CLICK, playSound);
function playSound(e:MouseEvent):void{
if(currentSongId < songList.length)
{
var mySoundURL:URLRequest = new URLRequest(songList[currentSongId]);
var mySound:Sound = new Sound();
mySound.load(mySoundURL);
var mySoundChannel:SoundChannel = new SoundChannel();
mySoundChannel = mySound.play();
currentSongId++;
mySoundChannel.addEventListener(Event.SOUND_COMPLETE,handleSoundComplete)
}
if(currentSongId == songList.length)
{
currentSongId = 0;
}
}
function handleSoundComplete(event:Event){
}

You should use functions to modulate what you do, this will make your code more readable.
private Array songList = new Array("test1.mp3", "test2.mp3");
public function onPlayBtnPressed(){
currentSongIndex = 0;
PlaySongFromIndex(currentSongIndex);
}
public function PlaySongFromIndex(songIndex:int){
//do what ever here to simply play a song.
var song:Sound = new Sound(songList[songIndex]).Play()
//Addevent listener so you know when the song is complete
song.addEventListener(Event.Complete, songFinished);
currentSongIndex++;
}
public function songFinished(e:Event){
//check if all the songs where played, if so resets the song index back to the start.
if(currentSongIndex < listSong.Length){
PlaySongFromIndex(currentSongIndex);
} else {
currentSongIndex=0;
}
}
This wont compile its just to show an exemple, hope this helps.

Related

CROSSFADE SOUND AS 3.0

I'm an AS 3.0 project where I'm getting into an array sounds to compose a particular set of phrases. The problem is that it sounds too much shock and wanted to make a crossfade effect to better attach a word to each other.
My problem is that I can not join them because every sound played one after another, is there any way to merge that can reach the end of a sound with the beginning of the next?
Thank you very much.
The code I'm working with is something like this:
for (iii = 0; iii < numpalabras; iii ++)
{
if (abuscar2 = abuscarArray[iii])
{
vocaliza(abuscar2, iii);
}
}
iii = 0;
localSound = lossonidosArray[iii];
var soundTrans:SoundTransform = new SoundTransform;
soundTrans=SoundMixer.soundTransform;
soundTrans.volume=1;
soundTrans.pan=0;
elcanal.soundTransform = soundTrans;
elcanal = localSound.play(85, 0, soundTrans);
elcanal.addEventListener(Event.SOUND_COMPLETE, locutapalabra);
}
function locutapalabra(event:Event)
{
if (iii < (ii))
{
iii=iii+1;
localSound = lossonidosArray[iii];
var soundTrans:SoundTransform = new SoundTransform;
soundTrans=SoundMixer.soundTransform;
soundTrans.volume=1;
soundTrans.pan=0;
elcanal.soundTransform = soundTrans;
elcanal = localSound.play(85, 0, soundTrans);
elcanal.addEventListener(Event.SOUND_COMPLETE, locutapalabra);
}
function vocaliza(abuscar2, iii)
{
if (datosXML.palabras.(palabra == abuscar2).palabra == abuscar2)
{
ii++;
elfic = "mp3/" + datosXML.palabras.(palabra == abuscar2).fichero;
var elsonido :Sound = new Sound();
elsonido.addEventListener(IOErrorEvent.IO_ERROR, errorprogreso);
var laurl:URLRequest = new URLRequest(elfic);
elsonido.load(laurl);
lossonidosArray[ii] = elsonido;
}
}
I am new to AS 3.0 programming and I do not get clear my code to make the words come together with each other, because I get to build such phrases of several words.
Thank you very much.
For cross-fading, you can use a tween library (like greensock) to tween the volume of the sound channel:
var sound:Sound = new Sound(...);
// start volume at 0
var soundChannel = sound.play(0, 0, new SoundTransform(0));
// tween volume to 1
TweenMax.to(soundChannel, 1, { volume: 1 } );
// half a second before the sound is complete, tween volume to 0
TweenMax.to(soundChannel, .5, {volume: 0, delay:(sound.length/1000)-.5});
var timer:Timer = new Timer(3000) //set to how long to wait
timer.addEventListener(TimerEvent.TIMER, nextSound);
function nextSound(e:Event):void
{
listenForNextSound(); //this is where you play your next sound
}
timer is a timer variable, and when 3 seconds pass (or however long you want) the next sound will start playing.
To make your timer variable a bit more accurate, you can make it the duration of the sound by listening for the COMPLETE Event:
yourTimer.addEventListener(Event.COMPLETE, function() {
timer.delay = yourTimer.length - howMuchTimeBefore;
});

Toggle Mute sound in Actionscript 3

I have several tracks of audio that are in sinc. I would like to have one "TitleMusic" ON from the start, And allow the user to toggle ON and off the other tracks. My code As it stands has the "TitleMusic" playing from the start with all the other tracks playing too. I need to switch "track8" and all the other tracks (not showing) around so they are off at the start.This took me a long time to get to this point, I just need some help turning it around. Thanks
import flash.media.Sound;
import flash.media.SoundChannel;
var soundOn:Boolean = true;//This music is ON when we start
var myMusic:TitleMusic = new TitleMusic();
var myChannel1:SoundChannel = myMusic.play(0,1000);//endless loop, in effect
var soundOn3:Boolean = true; //music is ON when we start
var myMusic3:track8 = new track8();
var myChannel3:SoundChannel = myMusic3.play(0,1000); // endless loop, in effect
var myTransform3:SoundTransform;
mySoundButton3.addEventListener(MouseEvent.CLICK,toggleSound3);
mySoundButton3.buttonMode = true;
mySoundButton3.mouseChildren = false;
function toggleSound3(e:MouseEvent)
{
if(soundOn3)
{
// turn sound off
myTransform3 = new SoundTransform();
myTransform3.volume = 0; // silent
myChannel3.soundTransform = myTransform3;
soundOn3 = false;
mySoundButton3.myButtonText.text = "click to turn sound ON";
}
else // sound is off
{
// turn sound on
myTransform3 = new SoundTransform();
myTransform3.volume = 1; // full volume
myChannel3.soundTransform = myTransform3;
soundOn3 = true;
mySoundButton3.myButtonText.text = "click to turn sound OFF";
}
}
Couldn't you just put this line right after mySoundButton3.mouseChildren = false;:
toggleSound3(null);
Or, to be more efficient with memory, you could do this:
Take this line:
var myChannel3:SoundChannel = myMusic3.play(0,1000);
and change it to:
var myChannel3:SoundChannel;
This makes it so you're not actually starting the sound right away, but just creating the pointer for it (var)
Then, in your turn on block right after // turn sound on:
if(!myChannel13){
myChannel3 = myMusic3.play(0,1000);
}
This checks to see if you've started the sound yet, if not, it creates/starts the sound
You'll also want to change this line in your sound off block:
myChannel3.soundTransform = myTransform3;
to this
if(myChannel13){
myChannel3.soundTransform = myTransform3;
}
That way, if the off button is clicked before the on button, it won't throw an error.

How do I loop and stop a sound using the same button in AS3?

I have 4 buttons on stage and I need a code that enables me to click on one of them, loop a specific sound "infinitely", and when it is clicked again, the sound stops. The sound is not initially playing. Also, while one of the sounds is looping, if I press another button, I'd like the previous sound to stop and the new one to play.
To help visualize this more, I will explain my project. I have to create an 'app' that is like an online guitar tuner. This feature is sort of what I would like to recreate:
http://www.gieson.com/Library/projects/utilities/tuner/
I don't even know where to begin with the coding... any help is greatly appreciated. Thank you!
The actual code is quite dependent on how you are loading in the sound, so I will write the "skeleton" for the code.
var currentSound:Sound = null;
var currentSoundChannel:SoundChannel;
var sound1:Sound = /* Load me */
var sound2:Sound = /* Load me */
button1.addEventListener(MouseEvent.CLICK, playSound1);
function playSound1(event:MouseEvent)
{
playSound(sound1);
}
button2.addEventListener(MouseEvent.CLICK, playSound2);
function playSound2(event:MouseEvent)
{
playSound(sound2);
}
function playSound(sound:Sound):void
{
if (currentSound != null)
{
// Stop the current music
currentSoundChannel.stop();
}
if (currentSound == sound)
{
// Stop playing ANY sound
currentSound = null;
currentSoundChannel = null;
}
else
{
// Play a different sound
currentSound = sound;
currentSoundChannel = sound.play();
}
}

action script to add a pause button on a few audio buttons

I am currently using the following code to play audio recordings from the project library.
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.events.MouseEvent;
var sound1:Sound = new audio1();
var sound2:Sound = new audio2();
var mySoundChannel:SoundChannel = new SoundChannel();
function stopSound():void
{
//This stops all sound in the sound channel.
//If there is nothing playing, nothing happens.
mySoundChannel.stop();
}
//In this function, we create an argument that allows us to tell the function
//what sound to we want it to play.
function playSound(soundname:String):void
{
try
{
mySoundChannel = this[soundname].play(0, 0);
}
catch(error:ReferenceError)
{
trace("playSound: That sound name doesn't exist.");
return;
}
}
//Hook up buttons-->
button1.buttonMode = true;
button1.useHandCursor = true;
button2.buttonMode = true;
button2.useHandCursor = true;
button1.addEventListener(MouseEvent.CLICK, button1click);
button2.addEventListener(MouseEvent.CLICK, button2click);
function button1click(evt:Event):void
{
stopSound();
playSound("sound1");
}
function button2click(evt:Event):void
{
stopSound();
playSound("sound2");
}
I need to pause the currently playing audio when a button is clicked. How do I do this?
You will need to do five things to your current code in order to pause and resume the currently playing sound:
Create a variable that stores the name of the currently playing
sound, and a variable to store the pause position of the audio.
Create a pause function.
Create a resume function.
Expand the current playSound and stopSound functions to work with the new variables.
Hook up the button event listener.
Step 1:
var currentSound:String = "";
var pausePosition:Number = 0;
Step 2: We're going to save the current position of the audio in that second variable we just created. We can get the current play position of the audio using the mySoundChannel.position property, which returns a Number value (matching the Number type we gave the pausePosition variable).
function pauseSound():void
{
//If there's a song to pause...
if(currentSound != "")
{
//Get pause position.
pausePosition = mySoundChannel.position;
//Stop the sound directly.
mySoundChannel.stop();
}
}
Note we didn't call stopSound(). There's a good reason for that. We're going to put an extra line of code in that function shortly that we don't want to use in pauseSound().
Step 3: Now we create the function to resume audio. Note this is NOT the same as playSound(). We're telling it to start playing from pausePosition, not from 0 (the beginning of the sound clip).
function resumeSound():void
{
//If there's a song to resume...
if(currentSound != "")
{
//Start playing the current audio from the position we left off at.
mySoundChannel = this[currentSound].play(pausePosition);
}
}
Step 4: Since we're now working with those variables we declared in step 1, we need to adjust how playSound() and stopSound() work.
In playSound(), instead of just passing soundname to the sound channel, we're going to save the soundname to currentSound.
function playSound(soundname:String):void
{
try
{
currentSound = soundname
mySoundChannel = this[currentSound].play(0, 0);
}
catch(error:ReferenceError)
{
trace("playSound: That sound name doesn't exist.");
return;
}
}
In stopSound(), we need to actually clear the currentSound and pausePosition variables when we stop, to ensure that resumeSound doesn't start audio after we've totally stopped it.
function stopSound():void
{
//This stops all sound in the sound channel.
//If there is nothing playing, nothing happens.
mySoundChannel.stop();
//Clear our variables.
currentSound = "";
pausePosition = 0;
}
GOTCHA WARNING: Ordinarily, you can loop audio by passing an integer other than 0 in the second argument (where I have the 5) in the following code:
mySoundChannel = this[currentSound].play(0, 5);
In the above code, the sound would play from the beginning, and repeat five times.
However, if you are starting the audio from any position other than 0, what will actually happen is that the audio will loop at the position you start at, not at the beginning.
That is to say, if you use this code:
mySoundChannel = this[currentSound].play(1000, 5);
The sound will loop five times, but every time the sound starts over in the loop, it will start playing from position 1000, and NOT the beginning of the sound (0).
I hope that answers your question!

Recyclable Sound Object in Actionscript 3?

Using ONE Sound() object in Actionscript3, how can I play a one MP3 and then, when the user chooses a different one, play a second sound, using the SAME Sound() object?
EDIT: See my answer for how I did it.
You cannot use same Sound object to play multiple files.
Once load() is called on a Sound object, you can't later load a different sound file into that Sound object. To load a different sound file, create a new Sound object.
Ok, I actually did it using the following code. My bug was somewhere else in the FLA file, but this works. I made an uninitialized global variable and created the Sound() object LOCALLY inside of a function. While I'm technically using multiple sound objects, my references are all pointing to ONE object. Additionally, I can call these methods over one another for easier coding. This works for me:
/* -------------
Sound player
functions
------------ */
var snd:Sound; //the sound object
var sndC:SoundChannel; //the soudchannel used as "controller"
var sndT:SoundTransform; //soundTransform used for volume
var vol:Number = 1; //the volume of the song
var pan:Number = 0; //panning of the sound
var pos:Number = 0; //position of the song
var currentSound:String; //currently playing song?
function playSound(s:String){ //this function resets the sound and plays it
stopSound(sndC); //stop the sound from playing
snd = new Sound(); //reset the sound
snd.load(new URLRequest(s)); //load the desired sound
sndC = new SoundChannel(); //(re-)apply the sound channel
applyVolume(vol,pan,sndT,sndC); //apply the volume
sndC = snd.play(pos); //play it
sndC.addEventListener(Event.SOUND_COMPLETE, startSound); //remind it to restart playing when it's done
} //end function
function applyVolume(n:Number, p:Number, st:SoundTransform, sc:SoundChannel){ //takes an argument for the volume, pan, soundTYransform and soundChannel
sndT = new SoundTransform(n,p); //applies the soundTransfrom settings
sndC.soundTransform = sndT; //and attaches it to the soundChannel
} //end function
function stopSound(sndC:SoundChannel){ //this function stops a sound from playing
if(sndC != null){ //if the sound was used before (ie: playing)
if(currentLabel == "video-frame"){ //if we are in the video frame
pos = sndC.position; //store the position of the song to play from at a later time
}else{ //otherwise
pos = 0; //set the position at 0
} //end if
sndC.stop(); //stop it
} //end if
} //end function
function startSound(snd:Sound){ //restarts a sound when it's playing
if(snd != null){ //if the sound exists
sndC = snd.play(pos); //play it
} //end if
} //end function