//SCRIPTING AND CONTROLLING SOUND
var mySound:Sound = new Sound(); //create Sound object and assign in the variable name mySound
var myChannel:SoundChannel = new SoundChannel(); //create SoundChannel, needed for controlling sound
var mySoundTransform:SoundTransform = new SoundTransform(); //create SoundTransform needed for volume and panning
var myFile:URLRequest = new URLRequest("track1.mp3"); //myFile is variable for the URLRequest
mySound.load(myFile); //loads the file/request into the sound object
var myPosition:Number = 0; //variable to track position of sound
var soundPlaying:Boolean = false; //variable to track if sound is playing or not
var skipSpeed:Number = 500; //variable for ff and rewind speed
//Add event listeners to all button
stop_btn.addEventListener(MouseEvent.CLICK, onClick);
play_btn.addEventListener(MouseEvent.CLICK, onClick);
pause_btn.addEventListener(MouseEvent.CLICK, onClick);
track1_btn.addEventListener(MouseEvent.CLICK, onClick);
track2_btn.addEventListener(MouseEvent.CLICK, onClick);
//For rewind and ff use MOUSE_DOWN and MOUSE_UP so that you can hold the buttons down for continous effect
rewind_btn.addEventListener(MouseEvent.MOUSE_DOWN, onSkipDown);
ff_btn.addEventListener(MouseEvent.MOUSE_DOWN, onSkipDown);
rewind_btn.addEventListener(MouseEvent.MOUSE_UP, onSkipUp);
ff_btn.addEventListener(MouseEvent.MOUSE_UP, onSkipUp);
function onClick(e:MouseEvent) {
//With the switch conditional and the event target(e.target) we can use one oClick function for each of these buttons
switch (e.target) {
case play_btn: //if the target is the play_btn do this
if (!soundPlaying) { //check if the sound is playing or not and if not do this
myChannel = mySound.play(myPosition); //play wit offset of myPosition var
myChannel.soundTransform = mySoundTransform; //apply any sound transformations too
soundPlaying = true; // now its true that the sound is playing
}
break; // use the break statement to end each case
case stop_btn:
myChannel.stop(); //stop the sound in the sound channel
soundPlaying = false;
myPosition = 0; //reset the position var to 0 (rewind it)
break;
case pause_btn:
myPosition = myChannel.position; //reset position var to current channel position to keep track of it
myChannel.stop();
soundPlaying = false
break;
case track1_btn: //change to track 1 -- stop the sound, say the sound is going to be new, and load/play it
myChannel.stop();
mySound = new Sound();
myFile = new URLRequest("track1.mp3");
mySound.load(myFile);
myPosition = 0;
myChannel = mySound.play(myPosition);
myChannel.soundTransform = mySoundTransform;
soundPlaying = true;
break;
case track2_btn: //change to track 2
myChannel.stop();
mySound = new Sound();
myFile = new URLRequest("track2.mp3");
mySound.load(myFile);
myPosition = 0;
myChannel = mySound.play(myPosition);
myChannel.soundTransform = mySoundTransform;
soundPlaying = true;
break;
}
}
//Rewind and FF functions
function onSkipDown(e:MouseEvent) {
switch (e.target) {
case rewind_btn: //use enterframe event to continously rewind while down
rewind_btn.addEventListener(Event.ENTER_FRAME, onRewind);
break;
case ff_btn: //use enterframe to continuously ff while down
ff_btn.addEventListener(Event.ENTER_FRAME, onFF);
break;
}
}
function onSkipUp(e:MouseEvent) {
skipSpeed = 500; //reset speed var
switch (e.target) {
case rewind_btn: //remove continous enterframe on up
rewind_btn.removeEventListener(Event.ENTER_FRAME, onRewind);
break;
case ff_btn: //remove continous enterframe on up
ff_btn.removeEventListener(Event.ENTER_FRAME, onFF);
break;
}
}
function onRewind(evt:Event) { //enterframe function to continously rewind
myPosition = myChannel.position - skipSpeed; //subtract speed from current position
skipSpeed +=100; //increase speed so rewind goes faster the longer you hold the buton down
myChannel.stop(); //stop the sound
myChannel = mySound.play(myPosition); //and replay from new position
myChannel.soundTransform = mySoundTransform; //maintaining all transformations on the sound
soundPlaying = true
}
function onFF(evt:Event) { //enterframe function to continously ff, similar to above for rewind
myPosition = myChannel.position + skipSpeed;
skipSpeed +=100;
myChannel.stop();
myChannel = mySound.play(myPosition);
myChannel.soundTransform = mySoundTransform;
soundPlaying = true
}
//VOLUME CONTROL - SLIDER BAR
//Note the bar is 100 pixels in height which will allow for an easy conversion of 0 to 100% sound volume
var constrain:Rectangle = new Rectangle(0, 0, 0, 100); //used to constrain the dragging of the slider
var mySetting:int = 100 - bar_mc.vslide_mc.y; //The mySetting var will be used to determine volume setting, its based on y position of slider
mySoundTransform.volume = mySetting/100; //divide transform by 100 sound that is within the range of 0 to 1 instead of 0 to 100
bar_mc.vslide_mc.buttonMode = true; //gives you the hand cursor when over vslide_mc clip/button
bar_mc.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
function onDown(e:MouseEvent) {
bar_mc.vslide_mc.startDrag(true ,constrain);//drag on down, set to the constraint so you can't drag outside of the bar
}
//bar_mc.addEventListener(MouseEvent.MOUSE_UP,onUp);
stage.addEventListener(MouseEvent.MOUSE_UP,onUp); //call also outside of bar_mc, otherwise you'll keep dragging after rollout
function onUp(e:MouseEvent) {
bar_mc.vslide_mc.stopDrag(); //stop dragging the slider
mySetting = 100 - bar_mc.vslide_mc.y; //reset the var based on slider y position
trace(mySetting)
mySoundTransform.volume = mySetting/100; //adjust sound volume based on new setting
myChannel.soundTransform = mySoundTransform;
}
//PANNING CONROL SLIDER BAR
//Panning works similar to volume slider, but with a wider bar of 200 pixels
var myPanSetting:int = 100 - panbar_mc.vslide_mc.y;
mySoundTransform.pan = myPanSetting/100;
var constrain2:Rectangle = new Rectangle(0, 0, 0, 200);
panbar_mc.vslide_mc.buttonMode = true;
panbar_mc.addEventListener(MouseEvent.MOUSE_DOWN, onPanDown);
function onPanDown(e:MouseEvent) {
panbar_mc.vslide_mc.startDrag(true ,constrain2);
}
panbar_mc.addEventListener(MouseEvent.MOUSE_UP,onPanUp);
stage.addEventListener(MouseEvent.MOUSE_UP,onPanUp);
function onPanUp(e:MouseEvent) {
panbar_mc.vslide_mc.stopDrag();
myPanSetting = 100 - panbar_mc.vslide_mc.y;
trace(myPanSetting)
mySoundTransform.pan = myPanSetting/100;
myChannel.soundTransform = mySoundTransform;
}
//KEEP TIME - Track current time and length of sound into text field
stage.addEventListener(Event.ENTER_FRAME, keepTime); //keep time updated every frame
function keepTime(e:Event) {
// position_txt.text = String(int(myChannel.position/1000)); //this would work but is in total seconds rather than 0:00 format
//variables for minutes, tens of seconds, and seconds so you can translate to 0:00 format from miliseconds
//first calculate current position
var minutes:Number = Math.floor(myChannel.position/60000); //minutes by dividing position by 60 seconds
var seconds10:Number = Math.floor(((myChannel.position/1000) % 60)/10); //to get tens of seconds value use modulo (%) for remainder
//modulo (%) returns remainder after division... so 10 % 6 would return 4 for example, whereas 10 % 5 returns 0 (no remainder)
var seconds:Number = Math.floor(((myChannel.position/1000) % 60)%10); //gets seconds from 0 - 9
//second calculate overall sound length
var lminutes:Number = Math.floor(mySound.length/60000);
var lseconds10:Number = Math.floor(((mySound.length/1000) % 60)/10);
var lseconds:Number = Math.floor(((mySound.length/1000) % 60)%10);
//third put all these variables into the text string for current position/song length
position_txt.text = String(minutes) + ":" + String(seconds10) +""+ String(seconds) + " | " + String(lminutes) + ":" + String(lseconds10) +""+ String(lseconds)
//keeping track of time has the added benefit of showing load progress as the sound length will continue to increase until sound fully loaded
//SOUND VISUALIZATION -- also running on the keepTime EnterFrame event
//rightPeak and leftPeak properties of the Sound Channel are easy ways to get amplitude info
//Here the peak data manipulates the mask named peakbar_mc to reveal bar
lpeakmeter_mc.peakbar_mc.height = myChannel.leftPeak * 200; //multiply by 200 to translate 0 to 1 into 0 to 200
rpeakmeter_mc.peakbar_mc.height = myChannel.rightPeak * 200;
//Compute Spectrum -- right click on computeSpectrum method to see flash help info upon which this is based
var bytes:ByteArray = new ByteArray();
//const PLOT_HEIGHT:int = 200;
const PLOT_HEIGHT:int = 398;
const CHANNEL_LENGTH:int = 256;
//SoundMixer.computeSpectrum(bytes, false, 0);
SoundMixer.computeSpectrum(bytes,true,0); //compute the spectrum and put in byte array
var g:Graphics = this.graphics; // will make graphics based on spectrum
g.clear(); //clear any current graphics
//left channel graphics
g.lineStyle(0, 0x000000, .5); //dictates line thickness, color, alpha)
g.beginFill(0x000000, .3); //fill color, alpha
g.moveTo(0, PLOT_HEIGHT); //set initial position of line
var n:Number = 0;
for (var i:int = 0; i < CHANNEL_LENGTH; i++) {
n = (bytes.readFloat() * PLOT_HEIGHT);
g.lineTo(i * 2.15, PLOT_HEIGHT - n); //draw line for all data in computeSpectrum byte array left channel (2.15 is the factor that will allow the graphics to extend all the way accross the stage (256 * 2.15 = 550, our stage with)
}
g.lineTo(CHANNEL_LENGTH * 2.15, PLOT_HEIGHT);
g.endFill();
//right channel graphics
g.lineStyle(0, 0xFFFFFF, .5);
g.beginFill(0xFFFFFF, 0.3);
g.moveTo(CHANNEL_LENGTH * 2.15, PLOT_HEIGHT);
for (i = CHANNEL_LENGTH; i > 0; i--) {
n = (bytes.readFloat() * PLOT_HEIGHT);
g.lineTo(i * 2.15, PLOT_HEIGHT - n);
}
g.lineTo(0, PLOT_HEIGHT);
g.endFill();
}