flash on 2010-11-13
マイク入力からのFFT
参考 : http://www.kurims.kyoto-u.ac.jp/~ooura/fftman/index.html
package
{
import flash.display.Sprite;
import flash.events.SampleDataEvent;
import flash.media.Microphone;
import flash.utils.ByteArray;
[SWF(width=465, height=465, backgroundColor=0xFFFFFF, frameRate=60)]
public class MicTest extends Sprite
{
private var _mic:Microphone;
public function MicTest()
{
_mic = Microphone.getMicrophone();
_mic.addEventListener(SampleDataEvent.SAMPLE_DATA, micSampleDataHandler);
}
private function micSampleDataHandler(evt:SampleDataEvent):void
{
var data:ByteArray = evt.data;
var n:uint = Math.min(data.length/ 4, 256) ;
var sound:Vector.<Number> = new Vector.<Number>();
for (var i:uint = 0; i < n; i++) {
sound.push(data.readFloat());
}
sound = computeSpectrum(sound);
var offsetW:int = (stage.stageWidth - (sound.length)) / 2;
var offsetH:uint = stage.stageHeight / 2;
graphics.clear();
graphics.lineStyle(1, 0x0);
for (var x:uint = 0; x < sound.length; x++) {
graphics.moveTo(x + offsetW, sound[x]*50 + offsetH);
graphics.lineTo(x + offsetW, -sound[x]*50 + offsetH);
}
}
private function computeSpectrum(data:Vector.<Number>):Vector.<Number>
{
var n:uint = data.length;
var theta:Number = 2 * Math.PI * n;
var i:uint;
var j:uint;
var k:uint;
var m:uint;
var mh:uint;
var irev:uint;
var wr:Number;
var wi:Number;
var xr:Number;
var xi:Number;
var ar:Vector.<Number> = data.slice(); // 入力データ実部
var ai:Vector.<Number> = new Vector.<Number>(n); // 入力データ虚部
var out:Vector.<Number> = new Vector.<Number>(n); // 出力データ
i = 0;
for (j = 1; j < n - 1; j++) {
for (k = n >> 1; k > (i ^= k); k >>= 1){}
if (j < i) {
xr = ar[j];
xi = ai[j];
ar[j] = ar[i];
ai[j] = ai[i];
ar[i] = xr;
ai[i] = xi;
}
}
for (mh = 1; (m = mh << 1) <= n; mh = m) {
irev = 0;
for (i = 0; i < n; i += m) {
wr = Math.cos(theta * irev);
wi = Math.sin(theta * irev);
for (k = n >> 2; k > (irev ^= k); k >>= 1) {}
for (j = i; j < mh + i; j++) {
k = j + mh;
xr = ar[j] - ar[k];
xi = ai[j] - ai[k];
ar[j] += ar[k];
ai[j] += ai[k];
ar[k] = wr * xr - wi * xi;
ai[k] = wr * xi + wi * xr;
}
}
}
// 出力の作成
for(i = 0; i < n; i++)
{
out[i] = Math.sqrt(ar[i]*ar[i] + ai[i]*ai[i]);
}
return out;
}
}
}