いわゆるフィルター。
一般的なものが最低限揃っている。
ソースを見る
class maxiFilter { double gain; double input; double output; double inputs[10]; double outputs[10]; double cutoff1; double x;//speed double y;//pos double z;//pole double c;//filter coefficient public: maxiFilter():x(0.0), y(0.0), z(0.0), c(0.0){}; double cutoff; double resonance; double lores(double input,double cutoff1, double resonance); double hires(double input,double cutoff1, double resonance); double bandpass(double input,double cutoff1, double resonance); double lopass(double input,double cutoff); double hipass(double input,double cutoff); };
//I particularly like these. cutoff between 0 and 1 double maxiFilter::lopass(double input, double cutoff) { output=outputs[0] + cutoff*(input-outputs[0]); outputs[0]=output; return(output); } //as above double maxiFilter::hipass(double input, double cutoff) { output=input-(outputs[0] + cutoff*(input-outputs[0])); outputs[0]=output; return(output); } //awesome. cuttof is freq in hz. res is between 1 and whatever. Watch out! double maxiFilter::lores(double input,double cutoff1, double resonance) { cutoff=cutoff1*0.5; if (cutoff<10) cutoff=10; if (cutoff>(maxiSettings::sampleRate*0.5)) cutoff=(maxiSettings::sampleRate*0.5); if (resonance<1.) resonance = 1.; z=cos(TWOPI*cutoff/maxiSettings::sampleRate); c=2-2*z; double r=(sqrt(2.0)*sqrt(-pow((z-1.0),3.0))+resonance*(z-1))/(resonance*(z-1)); x=x+(input-y)*c; y=y+x; x=x*r; output=y; return(output); } //working hires filter double maxiFilter::hires(double input,double cutoff1, double resonance) { cutoff=cutoff1*0.5; if (cutoff<10) cutoff=10; if (cutoff>(maxiSettings::sampleRate*0.5)) cutoff=(maxiSettings::sampleRate*0.5); if (resonance<1.) resonance = 1.; z=cos(TWOPI*cutoff/maxiSettings::sampleRate); c=2-2*z; double r=(sqrt(2.0)*sqrt(-pow((z-1.0),3.0))+resonance*(z-1))/(resonance*(z-1)); x=x+(input-y)*c; y=y+x; x=x*r; output=input-y; return(output); } //This works a bit. Needs attention. double maxiFilter::bandpass(double input,double cutoff1, double resonance) { cutoff=cutoff1; if (cutoff>(maxiSettings::sampleRate*0.5)) cutoff=(maxiSettings::sampleRate*0.5); if (resonance>=1.) resonance=0.999999; z=cos(TWOPI*cutoff/maxiSettings::sampleRate); inputs[0] = (1-resonance)*(sqrt(resonance*(resonance-4.0*pow(z,2.0)+2.0)+1)); inputs[1] = 2*z*resonance; inputs[2] = pow((resonance*-1),2); output=inputs[0]*input+inputs[1]*outputs[1]+inputs[2]*outputs[2]; outputs[2]=outputs[1]; outputs[1]=output; return(output); }
フィルタの実装
他にフィルタを実装しているライブラリを見て
参考にしようと探したところ
Robert Bristow-Johnsonという方が「RBJ Audio EQ Cookbook」というテキストにまとめているようだ。
説明は下記がわかりやすい。
上記を参考にソースを追ってみたい。
関数を読み解く
と、いろいろ調べていたところで
どうもMaximilianのローパス・ハイパスフィルタはもっとお手軽に実装しているようだ。
//I particularly like these. cutoff between 0 and 1 double maxiFilter::lopass(double input, double cutoff) { output=outputs[0] + cutoff*(input-outputs[0]); outputs[0]=output; return(output); } //as above double maxiFilter::hipass(double input, double cutoff) { output=input-(outputs[0] + cutoff*(input-outputs[0])); outputs[0]=output; return(output); }
output[0] + cutoff*(input-output[0])
となっている。
これは、加算平均というデジタルフィルタで、主にノイズの除去に使われている
計算に似ている。
しかし加算平均であれば
output[0]*(1-cutoff) + cuoff*(input-output[0])
とすべきだが、それをもっとお手軽にした形なのだろう。
ま、そういうものということで、この二つはいいかと思う。
次にlores,hiresをみよう。
//awesome. cuttof is freq in hz. res is between 1 and whatever. Watch out! double maxiFilter::lores(double input,double cutoff1, double resonance) { cutoff=cutoff1*0.5; if (cutoff<10) cutoff=10; if (cutoff>(maxiSettings::sampleRate*0.5)) cutoff=(maxiSettings::sampleRate*0.5); if (resonance<1.) resonance = 1.; z=cos(TWOPI*cutoff/maxiSettings::sampleRate); c=2-2*z; double r=(sqrt(2.0)*sqrt(-pow((z-1.0),3.0))+resonance*(z-1))/(resonance*(z-1)); x=x+(input-y)*c; y=y+x; x=x*r; output=y; return(output); } //working hires filter double maxiFilter::hires(double input,double cutoff1, double resonance) { cutoff=cutoff1*0.5; if (cutoff<10) cutoff=10; if (cutoff>(maxiSettings::sampleRate*0.5)) cutoff=(maxiSettings::sampleRate*0.5); if (resonance<1.) resonance = 1.; z=cos(TWOPI*cutoff/maxiSettings::sampleRate); c=2-2*z; double r=(sqrt(2.0)*sqrt(-pow((z-1.0),3.0))+resonance*(z-1))/(resonance*(z-1)); x=x+(input-y)*c; y=y+x; x=x*r; output=input-y; return(output); }