//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();
}