package evo.audio.dcf { import evoflash.audio.util.PrecalTableGenerator; import evoflash.audio.PCMSoundFormat; public class LowPassMoog implements IFilter { /* f = 0 .. 0.9*Fs/2 res = 0 .. 1.05 comp = 0 .. 1 (0 = moog, 0.5 = cem) wc = 2*pi*f/Fs g = 0.9892*wc - 0.4342*wc^2 + 0.1381*wc^3 - 0.0202*wc^4 fb = res*(1.0029 + 0.0526*wc^2 - 0.0926*wc^2 + 0.0218*wc^3) A = 0.769 B = 0.231 x1 = tanh(in - 4*fb*(y4 - comp*in)) y1 += g*(A*x1 + B*x1_b - y1) x1_b = x1; y2 += g*(A*y1 + B*x2_b - y2) x2_b = y1; y3 += g*(A*y2 + B*x3_b - y3) x3_b = y2; y4 += g*(A*y3 + B*x4_b - y4) x4_b = y3; */ private var tanh:Array; private var _res:Number = 0; private var _cutoff:Number = 0; private var _wc:Number; private var _wc2:Number; private var _wc3:Number; private var _wc4:Number; private var _g:Number; private var _fb:Number; private var y1:Number = 0; private var y2:Number = 0; private var y3:Number = 0; private var y4:Number = 0; private var x1_b:Number = 0; private var x2_b:Number = 0; private var x3_b:Number = 0; private var x4_b:Number = 0; private var _fmt:PCMSoundFormat; public function LowPassMoog(fmt:PCMSoundFormat, cutoff:Number, res:Number) { _fmt = fmt; tanh = PrecalTableGenerator.getTanhTable(); _cutoff = cutoff; _res = res; refresh(); } public function getCutoff():Number { return _cutoff; } public function getResonance():Number { return _res; } public function setCutoff(cutoff:Number):void { _cutoff = Math.min(Math.max(cutoff,0), 0.9*_fmt.sampleRate / 2); refresh(); } public function setResonance(res:Number):void { _res = Math.min(Math.max(res, 0), 1.05); refresh(); } public function refresh():void { _wc = Math.PI * 2 * _cutoff /_fmt.sampleRate; _wc2 = _wc*_wc; _wc3 = _wc*_wc*_wc; _wc4 = _wc*_wc*_wc*_wc; _g = 0.9892*_wc - 0.4342*_wc2 + 0.1381*_wc3 - 0.0202*_wc4; _fb = _res*(1.0029 + 0.0526*_wc - 0.0926*_wc2 + 0.0218*_wc3); } public function filterSample(sample:Number):Number { var A:Number = 0.769 var B:Number = 0.231 var x1:Number = tanh[uint(((sample - 4*_fb*y4)+16)*128)]; y1 += _g*(A*x1 + B*x1_b - y1) x1_b = x1; y2 += _g*(A*y1 + B*x2_b - y2) x2_b = y1; y3 += _g*(A*y2 + B*x3_b - y3) x3_b = y2; y4 += _g*(A*y3 + B*x4_b - y4) x4_b = y3; return y4; } } }