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 Tester

Distorted microphone audio in Chrome 23.0.1271.64 and 24.0.1312.5.

More information: http://code.google.com/p/chromium/issues/detail?id=159888

Oiriginal code snippet by Yukiya Okuda.
/**
 * Copyright luciferous ( http://wonderfl.net/user/luciferous )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/4Itj
 */

// forked from alumican_net's [Prototyping] Microphone Study #02 録音と再生
package
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.BlendMode;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageQuality;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.SampleDataEvent;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.media.Microphone;
    import flash.media.SoundCodec;
    import flash.media.Sound;
    import flash.media.SoundChannel;
    import flash.utils.ByteArray;
    import flash.utils.getTimer;
    
    /**
     * マイクから波形を録音する
     * 
     * @author Yukiya Okuda
     */
    public class Main extends Sprite
    {
        //----------------------------------------
        //CLASS CONSTANTS
        
        private const ZEROS:Point = new Point();
        
        
        
        
        //----------------------------------------
        //VARIABLES
        
        /**
         * マイクロフォン
         */
        private var _mic:Microphone;
        
        /**
         * 録音用
         */
        private var _records:Vector.<Number>;
        
        /**
         * 再生用
         */
        private var _sound:Sound;
        private var _soundChannel:SoundChannel;
        
        /**
         * 録音、再生ヘッダ
         */
        private var _position:int;
        
        /**
         * 描画用
         */
        private var _canvas:BitmapData;
        private var _slit:BitmapData;
        private var _over:Sprite;
        
        
        
        
        //----------------------------------------
        //STAGE INSTANCES
        
        
        
        
        
        //----------------------------------------
        //METHODS
        
        /**
         * コンストラクタ
         */
        public function Main():void
        {
            Wonderfl.disable_capture();
                        
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.quality = StageQuality.LOW;
            
            //_mic = Microphone.getMicrophone();
            _mic = Microphone.getEnhancedMicrophone();
            //_mic.codec = SoundCodec.SPEEX;
            _mic.rate = 44;
            _mic.framesPerPacket = 1;
            _mic.setSilenceLevel(0);
            _mic.setUseEchoSuppression(false);
            _mic.setLoopBack(false);
            _mic.encodeQuality = 10;
            
            _sound = new Sound();
            
            _canvas = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0xffffff);
            _slit = new BitmapData(1, stage.stageHeight, false, 0xffffff);
            addChild( new Bitmap(_canvas) );
            
            _over = addChild( new Sprite() ) as Sprite;
            _over.graphics.beginFill(0x0);
            _over.graphics.drawRect(0, 0, 100, 100);
            _over.graphics.endFill();
            
            _over.blendMode = BlendMode.INVERT;
            
            _startRecord();
        }
        
        /**
         * 録音開始
         */
        private function _startRecord():void
        {
            trace("_startRecord");
            
            _over.width = 0;
            
            _position = 0;
            //_records = new Vector.<Number>(44100 * 5);
            _records = new Vector.<Number>(44100 * 5);
            _mic.addEventListener(SampleDataEvent.SAMPLE_DATA, _micSampleDataHandler);
        }
        
        private function _micSampleDataHandler(e:SampleDataEvent):void
        {
            var sw:int = stage.stageWidth;
            var sh:int = stage.stageHeight;
            
            var datas:ByteArray = e.data;
            
            while (datas.bytesAvailable)
            {
                var data:Number = _records[_position] = datas.readFloat();
                
                if (_position % 3 == 0)
                {
                    var x:Number = _position / _records.length * sw;
                    var y:Number = sh * 0.5 - data * 1000;
                    _canvas.copyPixels(_slit, _slit.rect, new Point(x + 1, 0));
                    _canvas.setPixel(x, y, 0x0);
                }
                
                if (++_position == _records.length)
                {
                    _mic.removeEventListener(SampleDataEvent.SAMPLE_DATA, _micSampleDataHandler);
                    _startSound();
                    return;
                }
            }
        }
        
        /**
         * 再生開始
         */
        private function _startSound():void
        {
            trace("_startSound");
            
            _position = 0;
            _sound.addEventListener(SampleDataEvent.SAMPLE_DATA, _soundSampleDataHandler);
            _soundChannel = _sound.play();
        }
        
        private function _soundSampleDataHandler(e:SampleDataEvent):void
        {
            _over.width = stage.stageWidth * (_position / _records.length);
            _over.height = stage.stageHeight;
            
            for (var i:int = 0; i < 2048; ++i)
            {
                var data:Number = _records[_position];
                
                e.data.writeFloat(data);
                e.data.writeFloat(data);
                
                if (++_position == _records.length)
                {
                    _sound.removeEventListener(SampleDataEvent.SAMPLE_DATA, _soundSampleDataHandler);
                    _startRecord();
                    return;
                }
            }
        }
    }
}