For the code below, much code and concepts are from Adobe’s Working With Sound webpages, which is a great introductory resource to microphone audio. However, there is nothing about saving audio to a file. They delegate that to a media server, and seem to imply that there is no other way to save audio.

However, there is the flash.media.SoundMixer.computeSpectrum() method that delivers the byte data of a sound, and this works for both microphone and input audio file. This byte data can be saved to file, potentially, and I will update this post if I ever get around to doing that.

Anyway, for simple screwing around with audio, the following class is a starter. All it does is send the audio from your mic to your speakers – your own public address system!

Setup: It requires a Flash MovieClip in the library that inherits this class. Also, this object has to have some child MovieClip named activityMeter1, and a child TextField named activityLevel1.

package SoundRecorder
{
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.events.*;
    import flash.media.Microphone;
    import flash.system.Security;
    import flash.system.SecurityPanel;
    
    /**
     * ...
     * @author Delfeld, copyright 2008
     */
    public class SoundRecorder extends MovieClip {
        
        private static const SR_AUDIO_ALLOWED:String = "SRAudioAllowed";
        
        private var recordingAllowed:Boolean;
        private var mic:Microphone;
        
        public function SoundRecorder()
        {
            try
            {
                recordingAllowed = false;
                
                // setup mic
                mic = Microphone.getMicrophone();
                
                // confirm the mic settings first
                Security.showSettings(SecurityPanel.MICROPHONE);
                
                // listen for mic becoming active
                this.addEventListener(SR_AUDIO_ALLOWED, allowAudioHandler, false, 0, true);
                
                // call the mic popup, and confirm with user that they should use the mic.
                if (mic != null) {
                    // kill (some) feedback
                    mic.setUseEchoSuppression(true);
                    // send ALL mic input to the speaker
                    mic.setLoopBack(true);
                    // listen for events
                    mic.addEventListener(ActivityEvent.ACTIVITY, activityHandler, false, 0, true);
                    mic.addEventListener(StatusEvent.STATUS, statusHandler, false, 0, true);
                }
            }
            catch (e:Error)
            {
                trace("(caught error) SoundRecorder.SoundRecorder: " + e.toString() + " :\n.\n" + e.getStackTrace());
            }
        }
        
        // method is run when mic is activated
        private function allowAudioHandler(e:Event):void
        {
            e.target.removeEventListener(e.type, allowAudioHandler);
            
            setAudio();
        }
        
        // initial audio setup when the microphone is active
        private function setAudio():void
        {
            // this is in case of repeated calls to this method
            if (hasEventListener(Event.ENTER_FRAME))
            {
                removeEventListener(Event.ENTER_FRAME, changeDisplay);
            }
            
            mic.gain = 40;
            mic.rate = 16;
            mic.setSilenceLevel(5, 1000);
            
            // start displaying visuals on every frame
            addEventListener(Event.ENTER_FRAME, changeDisplay, false, 0, true);
        }
        
        private function changeDisplay(e:Event):void
        {
            if (recordingAllowed)
            {
                // resize the meter (really simple feedback)
                activityMeter1.height = 3 * mic.activityLevel;
                // note the mic level
                activityLevel1.text = mic.activityLevel.toFixed(0);
                
                // simple (and not great) control of mic level
                if (mic.activityLevel >= 99 && mic.gain > 25 )
                {
                    mic.gain -= 1;
                }
                else if (mic.activityLevel <= 0 && mic.gain < 75)
                {
                    mic.gain += 1;
                }
            }
        }
        
        private function activityHandler(event:ActivityEvent):void {
            //trace("activityHandler: " + event);
        }
        
        private function statusHandler(event:StatusEvent):void {
            if (event.code == "Microphone.Unmuted")
            {
                //trace("Microphone access was allowed.");
                recordingAllowed = true;
                dispatchEvent(new Event(SR_AUDIO_ALLOWED));
            }
            else if (event.code == "Microphone.Muted")
            {
                //trace("Microphone access was denied.");
                recordingAllowed = false;
            }
        }
    }
}

– 30 –

Advertisements