今日のStudy:オーディオ/フォルマント
注意:音出ます。
http://labs.zkdesign.jp/av512/512_15.html
musicdsp.orgというサイトを漁っていたら処理速度的に使えそうなフォルマントフィルタのアルゴリズムがあったので移植してみた。ノイズにかけたら音がゴルゴっぽくてウケた。
っていうか未だにBPFの計算式みたいのとかいった基本が全然何もわかってないので、これの特性をコントロール、とかが全然できないのが悩みどころ…。いい加減ちゃんと離散フーリエ変換とか学ぼうか…。
で、多分誰の役にも立たなそうだけど一応今回移植したソース。元のソースはこちら。
package { import de.popforge.audio.output.Sample; public class FormantFilter { // A,E,I,O,U private const coeff:Array=[ [ 3.11044e-06, 8.943665402,-36.83889529,92.01697887,-154.337906,181.6233289, -151.8651235,89.09614114,-35.10298511,8.388101016,-0.923313471 ], [ 4.36215e-06, 8.90438318,-36.55179099,91.05750846,-152.422234,179.1170248, -149.6496211,87.78352223,-34.60687431,8.282228154,-0.914150747 ], [ 3.33819e-06, 8.893102966,-36.49532826,90.96543286,-152.4545478,179.4835618, -150.315433,88.43409371,-34.98612086,8.407803364,-0.932568035 ], [ 1.13572e-06, 8.994734087,-37.2084849,93.22900521,-156.6929844,184.596544, -154.3755513,90.49663749,-35.58964535,8.478996281,-0.929252233 ], [ 4.09431e-07, 8.997322763,-37.20218544,93.11385476,-156.2530937,183.7080141, -153.2631681,89.59539726,-35.12454591,8.338655623,-0.910251753 ] ] private var memoryL:Array=[0,0,0,0,0,0,0,0,0,0]; private var memoryR:Array=[0,0,0,0,0,0,0,0,0,0]; public function FormantFilter() { } /** * * @param samples * @param vowelNum 0-4 = [A,E,I,O,U] */ public function processAudio(samples:Array,vowelNum:int=0):Array{ var smpl:Sample; var valL:Number; var valR:Number; var len:uint=samples.length; for(var i:int;i<len;++i){ smpl=samples[i]; valL=smpl.left; valR=smpl.right; //process Lch valL=coeff[vowelNum][0] * valL + coeff[vowelNum][1] *memoryL[0] + coeff[vowelNum][2] *memoryL[1] + coeff[vowelNum][3] *memoryL[2] + coeff[vowelNum][4] *memoryL[3] + coeff[vowelNum][5] *memoryL[4] + coeff[vowelNum][6] *memoryL[5] + coeff[vowelNum][7] *memoryL[6] + coeff[vowelNum][8] *memoryL[7] + coeff[vowelNum][9] *memoryL[8] + coeff[vowelNum][10] *memoryL[9]; //update Lch memory memoryL.unshift(valL); memoryL.pop(); //process Rch valR=coeff[vowelNum][0] * valR + coeff[vowelNum][1] *memoryR[0] + coeff[vowelNum][2] *memoryR[1] + coeff[vowelNum][3] *memoryR[2] + coeff[vowelNum][4] *memoryR[3] + coeff[vowelNum][5] *memoryR[4] + coeff[vowelNum][6] *memoryR[5] + coeff[vowelNum][7] *memoryR[6] + coeff[vowelNum][8] *memoryR[7] + coeff[vowelNum][9] *memoryR[8] + coeff[vowelNum][10] *memoryR[9]; //update Rch memory memoryR.unshift(valR); memoryR.pop(); //update sample smpl.left=valL; smpl.right=valR; } return(samples); } } }