|
Basic Sound Mixing
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();
}
}
}
|