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

[Prototyping] Microphone Study #02 録音と再生

マイクから波形を録音する

@author Yukiya Okuda
/**
 * Copyright alumican_net ( http://wonderfl.net/user/alumican_net )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/6D1n
 */

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.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.rate = 44;
			_mic.setSilenceLevel(0);
			_mic.setUseEchoSuppression(true);
			
			_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);
			_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;
				}
			}
		}
	}
}