[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;
}
}
}
}
}