Test pitch detection forked from: Simple spectrum analyzer (SiON FFT module + FP10.1 microphone)
SiON FFT module で 声紋解析 (Hamming窓+時間分解能11ms)
/**
* Copyright Alexisisaac ( http://wonderfl.net/user/Alexisisaac )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/ouyr
*/
// forked from keim_at_Si's Simple spectrum analyzer (SiON FFT module + FP10.1 microphone)
// forked from keno42's FP10.1用 マイク録音&再生
// SiON FFT module で 声紋解析 (Hamming窓+時間分解能11ms)
package {
import flash.display.*;
import flash.events.*;
import flash.media.*;
import flash.text.*;
import flash.utils.ByteArray;
import org.si.utils.FFT;
import frocessing.color.ColorLerp;
import com.bit101.components.*;
public class main extends Sprite {
private var voicePrint:BitmapData = new BitmapData(465, 256, false, 0);
private var mic:Microphone, scaler:HSlider;
public function main() {
_initFFT();
with(addChild(new Bitmap(voicePrint))){ y=100; }
(scaler = new HSlider(this, 100, 370, _onScalerChanged)).setSize(264, 20);
scaler.value = 1;
scale = 0.1;
mic = Microphone.getMicrophone();
mic.rate = 44;
mic.setSilenceLevel(0);
mic.setLoopBack();
mic.addEventListener("sampleData", _in);
}
private function _onScalerChanged(e:Event) : void {
scale = scaler.value;
}
private function _in(e:SampleDataEvent):void {
for (e.data.position=0; e.data.bytesAvailable>0;) {
_execFFT(e.data);
_updateImage();
}
}
private var oldVal:Array = new Array();
private function _updateImage() : void {
voicePrint.scroll(-1, 0);
var max:int=0;
var maxv:int = 0;
for (var j:int=255; j > 0; j--) {
if(maxv<frm[3][j]){
maxv = frm[3][j];
max = j;
}
}
for (var i:int=0; i < 256; i++) {
//voicePrint.setPixel(461, 255-i, 0);//grad[frm[3][i]]);
//voicePrint.setPixel(462, 255-i, 0);//grad[frm[2][i]]);
//voicePrint.setPixel(463, 255-i, 0);//grad[frm[1][i]]);
voicePrint.setPixel(464, 255-i, 0);//grad[frm[0][i]]);
voicePrint.setPixel(464, frmd[3][i]*255, 0xff0000);
}
oldVal.push(max);
if(oldVal.length>10){
oldVal.splice(1);
}
var mid:Number = 0;
for(var k:int = 0 ;k<oldVal.length;k++){
mid+=oldVal[k];
}
mid = Math.round(mid*255/oldVal.length);
voicePrint.setPixel(461, 255-mid, 0x00ff00);
//voicePrint.setPixel(461, 255-max, 0xffffff);
//voicePrint.setPixel(462, 255-max, 0xffffff);
//voicePrint.setPixel(463, 255-max, 0xffffff);
voicePrint.setPixel(464, 255-max, 0x0f0f0f);
}
private var src:Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>(4);
private var dst:Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>(4);
private var amp:Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>(4);
private var frm:Vector.<Vector.<int>> = new Vector.<Vector.<int>>(4);
private var frmd:Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>(4);
private var hamm:Vector.<Number> = new Vector.<Number>(2048);
private var fft:FFT = new FFT(2048);
private var grad:Array, scale:Number;
private function _initFFT() : void {
var i:int;
for (i=0; i<4; i++) {
src[i] = new Vector.<Number>(2048);
dst[i] = new Vector.<Number>(2048);
amp[i] = new Vector.<Number>(1024);
frm[i] = new Vector.<int>(256);
frmd[i] = new Vector.<Number>(256);
}
for (i=0; i<2048; i++) hamm[i]=0.54-Math.cos(i*0.00306796)*0.46;
ColorLerp.mode = "hsv";
grad = ColorLerp.gradient(0x000040, 0xff0000, 256);
scale = 25;
}
private function _execFFT(data:ByteArray) : void {
var index:int, i:int, j:int, n:Number,
f:Vector.<int>, a:Vector.<Number>, fd:Vector.<Number>,
s0:Vector.<Number> = src[0],
s1:Vector.<Number> = src[1],
s2:Vector.<Number> = src[2],
s3:Vector.<Number> = src[3];
for (index=3; index>=0; --index) {
for (i=0; i<512; i++) {
n = data.readFloat();
j = i; s0[j] = n * hamm[j];
j += 512; s1[j] = n * hamm[j];
j += 512; s2[j] = n * hamm[j];
j += 512; s3[j] = n * hamm[j];
}
a = amp[index];
f = frm[index];
fd = frmd[index];
fft.setData(s3).calcDCT().getMagnitude(a)
for (i=0; i<256; i++) { // from 86Hz to 5.6kHz
n = Math.log(a[i+4]*scale);
f[i] = int(((n<0) ? 0 : (n>1) ? 1 : n) * 255);
fd[i] = n;
}
s3 = s2;
s2 = s1;
s1 = s0;
s0 = src[index];
}
}
}
}