about
history
syntax
visu
arcade
goodies
wrappers
efficiency
examples
experiments
tabageos
tutorials
actiontad logo white
Basic Sound Mixing
 


The Code:      
package 
{
    
    import flash.display.Sprite;
    import flash.display.Graphics;
    import flash.display.GradientType;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.TimerEvent;
    import flash.media.Sound;
    import flash.media.SoundTransform;
    import flash.media.SoundMixer;
    import flash.media.SoundChannel;
    import flash.geom.Rectangle;
    import flash.geom.Matrix;
    import flash.utils.Timer;
    import flash.utils.ByteArray;
    import flash.text.TextField;
    import flash.ui.Mouse;
    
    [SWF(backgroundColor = '#c8c8c8', width = '500', height = '500')]
    
    
    public class SimpleSoundMixer extends Sprite  
    {
        
        [Embed(source="soundsers.mp3")]
        private var TheAmbience:Class;
        
        private var ambience:Sound = new TheAmbience();
        
        [Embed(source="drumsers.mp3")]
        private var TheDrums:Class;
        
        private var drums:Sound = new TheDrums();
        
        private var animationTimer:Timer = new Timer(100, 0);
        
        private var mixerTop:Sprite = new Sprite();
        
        private var mixerBottom:Sprite = new Sprite();
        
        private var theMixHolder:Sprite = new Sprite();
        
        private var ambienceControl:SoundChannel = new SoundChannel();
        private var drumControl:SoundChannel = new SoundChannel();
        
        private var ambienceVolume:Number = 0.5;
        private var drumsVolume:Number = 0.8;
        
        private var soundPan:Number = 0;
        
        private var volumeOneLine:Sprite;private var volumeOneFader:Sprite;
        private var volumeTwoLine:Sprite;private var volumeTwoFader:Sprite;
        
        private var ambienceTransform:SoundTransform;
        private var drumsTransform:SoundTransform;
        
        
        public function SimpleSoundMixer() 
        {
            
            /* to change volume and control each sound */
            ambienceTransform = new SoundTransform(ambienceVolume, soundPan);
            drumsTransform = new SoundTransform(drumsVolume, soundPan);
            
            /* top part of mixer box */
            mixerTop.graphics.lineStyle(0, 0x000000);
            mixerTop.graphics.drawRect(0, 0, 256, 100);
            mixerTop.x = 500/2-mixerTop.width/2; mixerTop.y=10;
            
            /* bottom part of mixer box */
            mixerBottom.graphics.lineStyle(0, 0x000000);
            mixerBottom.graphics.drawRect(0, 0, 256, 230);
            mixerBottom.x=mixerTop.x;mixerBottom.y=mixerTop.y+mixerTop.height;
            addChild(mixerTop);addChild(mixerBottom);
            
            /* the mix hold positions the graph
            the graph will be inside of theMixHolder */
            theMixHolder.x=mixerTop.x;
            theMixHolder.y=mixerBottom.y;
            addChild(theMixHolder);            
            
            /* catcher for whem mouse not over a fader yet fader still dragging */
            var catchMouse:* = new Sprite();
            catchMouse.graphics.beginFill(0xc8c8c8, 0.1);
            catchMouse.graphics.drawRect(0, 0, mixerBottom.width, mixerBottom.height);
            catchMouse.x=mixerBottom.x;catchMouse.y=mixerBottom.y;
            catchMouse.addEventListener(MouseEvent.MOUSE_UP, volumeStopMoveHandler);
            addChild(catchMouse);
            
            
            /* volume lines and faders */
            volumeOneLine=makeAVolumeLine();
            volumeOneLine.x=mixerBottom.x+25;volumeOneLine.y=mixerBottom.y+35;
            addChild(volumeOneLine);
            
            volumeTwoLine=makeAVolumeLine();
            volumeTwoLine.x=volumeOneLine.x+50;volumeTwoLine.y=volumeOneLine.y;
            addChild(volumeTwoLine);
            
            volumeOneFader=makeAFader();
            volumeOneFader.x=volumeOneLine.x-volumeOneFader.width/2;volumeOneFader.y=volumeOneLine.y+ambienceVolume*100;
            addChild(volumeOneFader);
            
            volumeTwoFader=makeAFader();
            volumeTwoFader.x=volumeTwoLine.x-volumeTwoFader.width/2;volumeTwoFader.y=volumeTwoLine.y+drumsVolume*100;
            addChild(volumeTwoFader);
            
            var soundLabel:* = new TextField();
            soundLabel.selectable = false;
            soundLabel.text = "synth";soundLabel.height = 20;
            soundLabel.x = volumeOneLine.x - 15;
            soundLabel.y = volumeOneLine.y - 20;
            soundLabel.addEventListener(MouseEvent.MOUSE_OVER, volumeStopMoveHandler);
            addChild(soundLabel);
            
            var drumLabel:* = new TextField();
            drumLabel.selectable = false;drumLabel.height = 20;
            drumLabel.text = "drums";
            drumLabel.x = volumeTwoLine.x - 15;
            drumLabel.y = volumeTwoLine.y - 20;
            drumLabel.addEventListener(MouseEvent.MOUSE_OVER, volumeStopMoveHandler);
            addChild(drumLabel);
            
            
            /* play and stop buttons */
            var playButton:Sprite = new Sprite();
            playButton.graphics.beginFill(0x6495ed);
            playButton.graphics.lineStyle(0, 0x000000);
            playButton.graphics.moveTo(0, 0);
            playButton.graphics.lineTo(0, 12);
            playButton.graphics.lineTo(10, 6);
            playButton.graphics.lineTo(0, 0);
            playButton.graphics.endFill();
            playButton.buttonMode = true;
            playButton.x = volumeTwoLine.x + 75;
            playButton.y = volumeTwoLine.y;
            
            addChild(playButton);
            playButton.addEventListener(MouseEvent.CLICK, playHandler);
            
            
            var stopButton:Sprite = new Sprite();
            stopButton.graphics.beginFill(0x000000);
            stopButton.graphics.lineStyle(0, 0x000000);
            stopButton.graphics.drawRect(0, 0, 10, 10);
            stopButton.graphics.endFill();stopButton.buttonMode = true;
            
            stopButton.x = playButton.x;
            stopButton.y = playButton.y +25;
            addChild(stopButton);
            stopButton.addEventListener(MouseEvent.CLICK, stopHandler);
            
            
            /* all other events added */
            volumeOneFader.addEventListener(MouseEvent.MOUSE_DOWN, volumeMoveHandler);
            volumeOneFader.addEventListener(MouseEvent.MOUSE_UP, volumeStopMoveHandler);
            volumeOneFader.addEventListener(MouseEvent.CLICK, volumeStopMoveHandler);
            
            volumeTwoFader.addEventListener(MouseEvent.MOUSE_DOWN, volumeMoveHandler);
            volumeTwoFader.addEventListener(MouseEvent.MOUSE_UP, volumeStopMoveHandler);
            volumeTwoFader.addEventListener(MouseEvent.CLICK, volumeStopMoveHandler);
            
            /* volume control */
            addEventListener(Event.ENTER_FRAME, volumeControl);            
            
            /* initialize */
            startsounds();
            
            animationTimer.addEventListener(TimerEvent.TIMER, makeMixBars);
            drums.addEventListener(Event.SOUND_COMPLETE, stopBars);
            animationTimer.start();
            
            
        }
        
        private function playHandler(event:MouseEvent):void 
        {
                if (animationTimer.running == false)
                {startsounds();animationTimer.start();}
        }
        
        private function stopHandler(event:MouseEvent):void 
        {
             
                if (animationTimer.running == true)
                {ambienceControl.stop();drumControl.stop();animationTimer.stop();}         
        }
        
        private function startsounds():void 
        {
            /* add each sound to its own channel
            and set them playing from the beginning, and to loop 500 times
            using their individual soundTransform objects */
            
            ambienceControl = ambience.play(0, 500, ambienceTransform);
            drumControl = drums.play(0, 500, drumsTransform);
        }
        
        
        private function makeAFader():Sprite 
        {
            var vfader:Sprite = new Sprite();
            vfader.graphics.lineStyle(0, 0x6495ed);
            vfader.graphics.beginFill(0x000000);
            vfader.graphics.drawRect(0, 0, 30, 5);
            vfader.buttonMode = true;
            return(vfader);
        }
        
        
        private function makeAVolumeLine():Sprite 
        {
            var voline:Sprite = new Sprite();
            voline.graphics.lineStyle(1, 0x000000);
            voline.graphics.lineTo(0, 100);
            return(voline);
        }
        
        
        private function volumeStopMoveHandler(e:MouseEvent):void 
        {
            volumeOneFader.stopDrag();
            volumeTwoFader.stopDrag();
        }
        
        
        private function volumeMoveHandler(event:MouseEvent):void 
        {
            var xposition:Number =  
            (event.target.x == volumeOneFader.x) ? volumeOneLine.x-event.target.width/2 : volumeTwoLine.x-event.target.width/2;
            var draglock:Rectangle = 
            new Rectangle(xposition, volumeOneLine.y, volumeOneLine.width, volumeOneLine.height);
            event.target.startDrag(true, draglock);
        }
        
        
        
        private function volumeControl(e:Event):void 
        {
            /* 145 is the top y position of each volume line
            each volume line has a length of 100
            so at the bottom of each volume line the y position is 245
            
            the vfader y number gets greator as the fader moves down
            so at the bottom it is 245 minus 245
            at the top 245 minus 145 */
            
            var synthvol:Number = 245-volumeOneFader.y;
            var drumsvol:Number = 245-volumeTwoFader.y;
            
            /* convert to decimal */
            
            drumsVolume = drumsvol/100;
            ambienceVolume = synthvol/100;
            
            /* apply the above to each sounds volume
            the faders y position can fall below zero
            so have volume just stay at zero and not below
            this happens on enter frame thereby changing volume levels */
            
            ambienceTransform.volume = ambienceVolume<=0 ? 0 : ambienceVolume;
            ambienceControl.soundTransform = ambienceTransform;
            
            drumsTransform.volume = drumsVolume<=0 ? 0 : drumsVolume;
            drumControl.soundTransform = drumsTransform;
        }
        
        
        private function makeMixBars(event:TimerEvent):void 
        {
            var soundbytes:ByteArray = new ByteArray();
            /* the computeSpectrum method is doing most of the work for the graph
            returning the sound playing as binary data
            either a frequency spectrum  true
            or the raw wave data  false */
            SoundMixer.computeSpectrum(soundbytes, true, 0);
            
            var gra:Graphics = theMixHolder.graphics;
            gra.clear();gra.lineStyle(0, 0x6495ed);
            
            /* draw bars to go along with the bytes
            giving the bars a gradient top via the Matrix and beginGradientFill methods */
            
            var coluni:Array /* of hex values */ = [0x000000, 0x6495ed];
            var gramatrix:Matrix = new Matrix();
            
            var sh:*;
            for (var i:int = 0; i < 256; i+=4) {
                sh = (soundbytes.readFloat() * 95);
                gramatrix.createGradientBox(i, -sh-3, Math.PI/2, 0, 0);
                gra.beginGradientFill(GradientType.LINEAR, coluni, [1, 1], [127, 255], gramatrix);
                gra.drawRect(i, 0, 4, -sh-3);
            }
            
            gra.endFill();
            
        }
        
        
        
        private function stopBars(event:Event):void  
        {
            animationTimer.stop();           
        }
        
        
        
    }
    
}



Compiled Result:










actiontad twitter.com/actiontad terms