In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Microphone Record Play Bitmap Wave Graph

Click to switch between playing and recording.

I know there are better ways to do what I did here, but this was just hacked up pretty quickly, and meant to show how it's done.

I tried to comment pretty well, but I know it's not exactly pretty/reusable code; thus, if you have questions just ask.
//Originally written by NME a.k.a.  Anthony R Pace
package {
    import flash.events.StatusEvent;
    import flash.text.TextField;
    import flash.geom.Rectangle;
    import flash.utils.ByteArray;
    import flash.events.SampleDataEvent;
    import flash.media.Microphone;
    import flash.display.BitmapData;
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.media.Sound;
    public class PlayRecordShow0_1 extends Sprite    {
        public var bmp:Bitmap = new Bitmap(new BitmapData(512,stage.stageHeight,false,0x3CD8FF)), //the bitmap that will be used to represent the time domain
               mic:Microphone = Microphone.getMicrophone(),
               sn:Number,  //sample value at n, or s[n] 
               sampleRect:Rectangle = new Rectangle(0,0,4,20),//the spot on the line that represents the sample at a given point s[n]
               A:Number = ((stage.stageHeight-sampleRect.height)/2),//'A'  for amplitude factor.  In this case (stageHeight - sampeRect.height)/2
               recording:ByteArray = new ByteArray(),
               sound:Sound = new Sound(),
               isRecording:Boolean=true,
               bafg:ByteArray= new ByteArray(),// temp byte array for graph
               tf:TextField = new TextField();
        public function drawGraph(ba:ByteArray):void{
            var loopMax:Number = ba.length/4;//updated from fork, because bug was annoying.
            if (loopMax>512){
                loopMax = 512;
            }
            ba.position = 0;
            bmp.bitmapData.lock();
            bmp.bitmapData.fillRect(bmp.bitmapData.rect,0x3CD8FF); 
            for (var n:int = 0; n<loopMax; ++n){
                sn = ba.readFloat();//reads 4 bytes = 32 bit floating point sample value
                sampleRect.x = n-2;// as the width of the sample rect is 4, and we want 2 on each side.  We could constraine this within bounds but I'm not going to.
                sampleRect.y = A-sn*A; //In this case we are using A as the offest and the Amplitude; thus, YOffset - Amplitude*(the PCMvalue for S[n])
                bmp.bitmapData.fillRect(sampleRect,0xd7f7ff);
            }
            bmp.bitmapData.unlock();
        }
        public function micSDEH(e:SampleDataEvent):void{//sample data event handler
            e.data.position = 0;
            recording.writeBytes(e.data);
            drawGraph(e.data);
        }
        public function playBackSDEH(e:SampleDataEvent):void{
            var n:int = 0,
                floatsLeft:uint =(recording.length-recording.position)/4,
                emptySpaceCount:int = 0,//float is at 2048/512 = 4, so that means 3 out of 4 will be empty, so we need to fill the empty space
                lastValue:Number,//oh, and keep in mind that for stereo, you need to take my mono data and convert it to Left,Right,L,R,L,R,L,R,....
                qMDiff:Number, //will be used to hold a quarter of the difference in magnitude, between x and x + 1
                loopMax:int,
                ed:ByteArray = e.data;
            ed.position = 0;
            bafg.position = 0;
            if (floatsLeft>2048){
                loopMax = 2048;
            }else{
                loopMax = floatsLeft;
            }
            while (n<loopMax){//just filling in the gaps with lastValue using knowledge of empty space for now
                    if (emptySpaceCount==0){
                        lastValue = recording.readFloat();
                        ed.writeFloat(lastValue);
                        bafg.writeFloat(lastValue);
                        emptySpaceCount = 3;
                        ed.writeFloat(lastValue);    
                        qMDiff = (recording.readFloat() - lastValue) * 0.25;
                        recording.position -= 4;
                    }else{
                        lastValue += qMDiff;
                        ed.writeFloat(lastValue);
                        ed.writeFloat(lastValue);
                        --emptySpaceCount;
                    }
                    ++n;
            }
            drawGraph(bafg);
            if(floatsLeft<=2048){
                startRecording();
            }
        }
        public function startRecording():void{
            sound.removeEventListener(SampleDataEvent.SAMPLE_DATA,playBackSDEH,false);
            recording.clear();
            mic.addEventListener(SampleDataEvent.SAMPLE_DATA,micSDEH,false);
            isRecording = true;
            echo('Status: Recording Audio --- Left click to Stop recording and Start playback');
        }
        public function startPlaying():void{
            mic.removeEventListener(SampleDataEvent.SAMPLE_DATA,micSDEH,false);
            recording.position = 0;
            sound.addEventListener(SampleDataEvent.SAMPLE_DATA,playBackSDEH,false);
            sound.play(0);
            isRecording = false;
            echo('Status: Playing Audio --- Left click to Stop playback and Start recording');
        }
        public function mch(e:MouseEvent):void{
            if (isRecording == true && recording.length>4) {
                startPlaying();
           }else {
                startRecording();
           }
        }
        public function micStatusEH(e:StatusEvent):void{
            mic.removeEventListener(StatusEvent.STATUS, micStatusEH,false);
                if (e.code == "Microphone.Unmuted"){
                    stage.addEventListener(MouseEvent.CLICK, mch,false);   
                    echo('Status: Recording Audio --- Left click to Stop recording and Start playback');
                }else if (e.code == "Microphone.Muted") { 
                    echo("Status: Access to the Microphone was Denied :>  Please Reload.");
                }                       
        }
        public function echo(s:String = ''):void{tf.text = s; tf.width = tf.textWidth + 4;}
        public function PlayRecordShow0_1():void{
            stage.addChild(bmp);//make the bitmap visible on the display list;
            stage.addChild(tf);//add tf advise to state if recording
            echo('Status: Waiting for Microphone access to be granted');         
            mic.rate = 11;// sets N, the sample frequency to 11025
            mic.setSilenceLevel(0);//setting this to 0 makes it so you hear all activity;
            mic.addEventListener(SampleDataEvent.SAMPLE_DATA,micSDEH,false);// call the micSDEH function if the mic hears audio;
            mic.addEventListener(StatusEvent.STATUS, micStatusEH,false);//mic status event handler
        }
    }
}