frocessing with SoundMixer


サウンドから生成するバイト配列をパラメータとしてfroccessingでグラフィックを描画するアプリケーションです。
入力デバイスからのインタラクションはありません。ただ眺めるだけっす。

frocessing with SoundMixer – wonderfl build flash online

以下、ちょっとした解説。
詳しくはwonderflのコードを見たほうが分かりやすいかもしれませんが・・・

frocessingでの描画処理部分のコード

import frocessing.display.*;
import flash.geom.Point;
import flash.utils.ByteArray;
import flash.media.SoundMixer;
  
class Canvas extends F5MovieClip2DBmp{ 
	private var _w:Number;
	private var _h:Number;
	private var _t:Number = 0;
	private var _pastPos:Point;
	private var _px:Number = 0;
	private var _py:Number = 0;
	private var _r:Number = 0;
	private var _list:Array = new Array();
	private var _soundPath:String;
	private var _waveBytes:ByteArray = new ByteArray();
	private var _sound:SoundPlayStop;
    
	public function Canvas($w:Number, $h:Number, $soundPath:String) {
		_w = $w;
		_h = $h;
		_soundPath = $soundPath;
		super();
	}
    
    // 初期化
	public function setup():void {
		for(var i:uint=0; i<5; i++){
			var p:Point = new Point(random(0 ,_w), random(0 ,_h));
			_list.push(p);
		}
		size(_w, _h);
		background(0);
		noFill();
		colorMode(HSV, 2, 1, 1);
		//
		_sound=new SoundPlayStop();
        _sound.soundStart(_soundPath, 100);
	}

	// 毎フレーム描画
	public function draw():void{
		// SoundMixerからバイト配列を取得して現実的な値に置き換える
		var n:int;
        try{
        	SoundMixer.computeSpectrum(_waveBytes, true, 0);
        	n = _waveBytes.readFloat() * 250;
        }catch(e:Error){
        	return;
        }
		//
		var rad = _r * .3 * Math.PI / 180;
		var px:Number = _w * .5 + Math.cos(rad) * n;
		var py:Number = _h * .5 + Math.sin(rad) * n;
		//
		var p:Point;
		p = new Point(px, py);
		
		//描画
		if(p && _pastPos){
			var distance:int = Point.distance(p, _pastPos);
			_pastPos = p;
            //
			var r:int = Math.random() * 10
			for(var i:int; i<distance * .5 ;i++){
				stroke(_t, 0.8, 1, 0.1);
				_px += (p.x + (Math.random() * distance-distance / 4) - _px) * Math.random() * 0.5;    
				_py += (p.y + (Math.random() * distance-distance / 4) - _py) * Math.random() * 0.5;
				ellipse(_px, _py, r * distance / 4, r * distance / 4);
			}
			_pastPos = p;
		}else{
			_pastPos = new Point(px, py);
		}
		_t += 0.1;
		_r += 30;
	}
	
	// 消す
	public function remove():void{
		background(0, 1);
		_t = 0;
	}
}
 

メインクラスでのエフェクト部分のコード

 public function Main(){
	addChild(_container); // ルート表示オブジェクト
	_canvas = new Canvas(WIDTH, HEIGHT, SOUNDPATH); // frocessingの表示オブジェクト
	_bmd = new BitmapData(WIDTH, HEIGHT, true, 0); // エフェクト用Bmd
	_container.addChild(_canvas);
	_container.addChild(_bm = new Bitmap(_bmd) as Bitmap);
	_bm.blendMode = "add";
	//
	addEventListener(Event.ENTER_FRAME, update);
	// 描画クリア用タイマー
	_timer = new Timer(500);
	_timer.addEventListener(TimerEvent.TIMER, removedInterval);
	_timer.start();
}
		
private function update(e:Event):void{
	// ColorTransformで色を暗くしながらエフェクト用BmdにCanvasをDraw
	_bmd.draw(_canvas, null, _ctf, "add");
	// エフェクト用Bmdにブラーフィルタを適用
	_bmd.applyFilter(_bmd, _bmd.rect, new Point(), new BlurFilter(8, 8, 3));
}
		
private function removedInterval(e:TimerEvent):void{
	// Canvasをクリア
	_canvas.remove();
}