forked from: Microphone Sample
/**
* Copyright hacker_fg4p6egw ( http://wonderfl.net/user/hacker_fg4p6egw )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/v7fu
*/
// forked from ll_koba_ll's Microphone Sample
package {
import flash.display.Sprite;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.media.Microphone;
import flash.media.SoundMixer;
import flash.media.SoundTransform;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import flash.geom.Matrix;
import flash.ui.Keyboard;
import flash.utils.ByteArray;
import flash.net.FileReference;
import com.adobe.images.PNGEncoder;
import com.adobe.images.JPGEncoder;
[SWF(backgroundColor="#FFFFFF", frameRate=30)]
public class MicrophoneSample01 extends Sprite {
private var _mic:Microphone;
private var _canvas:BitmapData;
private var _color:uint = 0xFF0000;
private var _colors:Array = [0xFF0000, 0x00FF00,0x0000FF,0xFFFF00,0x00FFFF, 0xFF00FF];
private const CANVAS_WIDTH:Number = 465;
private const CANVAS_HEIGHT:Number = 465;
public function MicrophoneSample01() {
// マイク準備
_mic = Microphone.getMicrophone();
_mic.setLoopBack(true);
// ハウリング対策でボリュームを0にする
var stf:SoundTransform = SoundMixer.soundTransform;
stf.volume = 0;
SoundMixer.soundTransform = stf;
// 描画対象
_canvas = new BitmapData(CANVAS_WIDTH, CANVAS_HEIGHT, false, 000000);
addChild(new Bitmap(_canvas));
// enterframeで音量を監視して処理を行う
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
// spaceで画像保存
stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
}
private function keyUpHandler(e:KeyboardEvent):void {
// キーボード
switch(e.keyCode) {
case Keyboard.SPACE:
saveImage();
break;
default:
break;
}
}
private function enterFrameHandler(e:Event):void {
// マイクが有効でなければ処理しない
if (_mic.muted) return;
var level:Number = _mic.activityLevel;
// マイクのレベルが一定以上でなければ処理しない
if (level < 50) return;
// インクを生成して描画する
var mtx:Matrix = new Matrix();
var inkx:Number = Math.random()*CANVAS_WIDTH;
var inky:Number = Math.random()*CANVAS_HEIGHT;
mtx.translate(inkx, inky);
var ink:Ink = new Ink(Math.random()*level/2, _color);
BitmapDataUtil.loopDraw(_canvas, ink, mtx);
// 色を変更
changeRandomColor();
}
private function changeRandomColor():void {
var n:int = (Math.random()*_colors.length)
_color = _colors[n+1];
_colors.alpha=0.9
}
private function saveImage():void {
// BitmapDataをPNGのbyteArrayに
var ba:ByteArray = PNGEncoder.encode(_canvas);
// jpgの場合
//var jpg:JPGEncoder = new JPGEncoder();
//var ba:ByteArray = jpg.encode(_canvas);
// pngをローカルへ保存
var file:FileReference = new FileReference();
file.save(ba, "captureimage.png");
}
}
}
import flash.display.Sprite;
import flash.display.Graphics;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.filters.DisplacementMapFilter;
class Ink extends Sprite {
private var _size:Number;
private var _color:uint;
public function Ink(size:Number, color:uint):void {
_size = size;
_color = color;
// 真ん中に一つ
create(size, 0,0);
// 周りにいくつか
var count:Number = Math.random()*10;
for (var i:int = 0; i < count; i++) {
// 角度
var r:Number = Math.random()*2*Math.PI;
var maxv:Number = size*3;
// 中心からの距離
var v:Number = Math.random()*maxv;
// 距離によってサイズ変更
var s:Number = size*Math.pow(((maxv-v)/maxv), 2);
// 距離と角度から位置を決定してインク追加
create(s, v*Math.cos(r), v*Math.sin(r));
}
// 全体にゆがみをかける
var mapw:Number = width * 2;
var maph:Number = height * 2;
var map:BitmapData = new BitmapData(mapw, maph, false, 0x000000);
map.perlinNoise(mapw,maph,3,Math.random(),true,false, 7, true);
var f:DisplacementMapFilter = new DisplacementMapFilter(
map, new Point(), 1, 1, size, size, "color"
);
filters = [f];
}
private function create(size:Number, _x:Number, _y:Number):void {
// 指定された、位置にサイズに円を追加
size = (size < 1)? 1 : size;
var ink:Sprite = new Sprite();
var g:Graphics = ink.graphics;
g.beginFill(_color);
g.drawCircle(0,0,size);
g.endFill()
addChild(ink);
ink.x = _x;
ink.y = _y;
}
}
import flash.display.BitmapData;
import flash.display.IBitmapDrawable;
import flash.display.DisplayObject;
import flash.geom.Rectangle;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
class BitmapDataUtil
{
public function BitmapDataUtil()
{
}
/**
* sourceがはみ出た分、回り込んでdrawしてくれる
* 回り込んだのがさらにはみ出た場合は考慮されていない
*/
public static function loopDraw(targetBitmapData:BitmapData,
source:IBitmapDrawable,
matrix:Matrix = null,
colorTransform:ColorTransform = null,
blendMode:String = null,
clipRect:Rectangle = null,
smoothing:Boolean = false
):void {
// 最終的にdrawするBitmapDataを生成
var tmpBitmapData:BitmapData = new BitmapData(targetBitmapData.width,
targetBitmapData.height,
true,
0x00FFFFFF);
var targetRect:Rectangle = targetBitmapData.rect;
// ソースのrect
var sourceRect:Rectangle;
if (source as BitmapData) {
var b:BitmapData = source as BitmapData;
sourceRect = b.rect;
} else if(source as DisplayObject) {
var d:DisplayObject = source as DisplayObject;
sourceRect = d.getRect(d);
} else {
return;
}
if (matrix != null) {
sourceRect.x += matrix.tx;
sourceRect.y += matrix.ty;
}
tmpBitmapData.draw(source, matrix);
var translateX:Number = 0;
var translateY:Number = 0;
// x方向
if (sourceRect.left < 0) {
translateX = targetBitmapData.width;
} else if (sourceRect.right > targetRect.right) {
translateX = -targetBitmapData.width;
}
// y方向
if (sourceRect.top < 0) {
translateY = targetBitmapData.height;
} else if (sourceRect.bottom > targetRect.bottom) {
translateY = -targetBitmapData.height;
}
// 各方向へずらしてdraw
matrix.translate(translateX,0);
tmpBitmapData.draw(source, matrix);
matrix.translate(0, translateY);
tmpBitmapData.draw(source, matrix);
matrix.translate(- translateX, 0);
tmpBitmapData.draw(source, matrix);
targetBitmapData.draw(tmpBitmapData,
null,
colorTransform,
blendMode,
clipRect,
smoothing);
}
}