-- | Time-domain filter unit generators. module Sound.SC3.UGen.Filter where import Data.List import Sound.SC3.UGen.Rate import Sound.SC3.UGen.Type import Sound.SC3.UGen.UGen -- | Audio to control rate converter. a2K :: UGen -> UGen a2K i = mkOscR [KR] KR "A2K" [i] 1 -- | Allpass filter (no interpolation) allpassN :: UGen -> UGen -> UGen -> UGen -> UGen allpassN i mt dly dcy = mkFilter "AllpassN" [i,mt,dly,dcy] 1 -- | Allpass filter (linear interpolation) allpassL :: UGen -> UGen -> UGen -> UGen -> UGen allpassL i mt dly dcy = mkFilter "AllpassL" [i,mt,dly,dcy] 1 -- | Allpass filter (cubic interpolation) allpassC :: UGen -> UGen -> UGen -> UGen -> UGen allpassC i mt dly dcy = mkFilter "AllpassC" [i,mt,dly,dcy] 1 -- | Basic psychoacoustic amplitude compensation. ampComp :: UGen -> UGen -> UGen -> UGen ampComp f r e = mkFilter "AmpComp" [f,r,e] 1 -- | ANSI A-weighting curve psychoacoustic amplitude compensation. ampCompA :: UGen -> UGen -> UGen -> UGen -> UGen ampCompA f r ma ra = mkFilter "AmpCompA" [f,r,ma,ra] 1 -- | Bandpass filter bpf :: UGen -> UGen -> UGen -> UGen bpf i freq rq = mkFilter "BPF" [i,freq,rq] 1 -- | Two zero fixed midpass filter. bpz2 :: UGen -> UGen bpz2 i = mkFilter "BPZ2" [i] 1 -- | Band reject filter brf :: UGen -> UGen -> UGen -> UGen brf i freq rq = mkFilter "BRF" [i,freq,rq] 1 -- | Two zero fixed midcut filter. brz2 :: UGen -> UGen brz2 i = mkFilter "BRZ2" [i] 1 -- | Clip input between lower and upper bounds. clip :: UGen -> UGen -> UGen -> UGen clip i l h = mkFilter "Clip" [i,l,h] 1 -- | Comb filter (no interpolation) combN :: UGen -> UGen -> UGen -> UGen -> UGen combN i mt dly dcy = mkFilter "CombN" [i,mt,dly,dcy] 1 -- | Comb filter (linear interpolation) combL :: UGen -> UGen -> UGen -> UGen -> UGen combL i mt dly dcy = mkFilter "CombL" [i,mt,dly,dcy] 1 -- | Comb filter (cubic interpolation) combC :: UGen -> UGen -> UGen -> UGen -> UGen combC i mt dly dcy = mkFilter "CombC" [i,mt,dly,dcy] 1 -- | Compressor,expander,limiter,gate,ducker. compander :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen compander i c t sb sa ct rt = mkFilter "Compander" [i,c,t,sb,sa,ct,rt] 1 -- | Convert signal to modal pitch. degreeToKey :: UGen -> UGen -> UGen -> UGen degreeToKey b i o = mkFilter "DegreeToKey" [b,i,o] 1 -- | Exponential decay. decay :: UGen -> UGen -> UGen decay i dcy = mkFilter "Decay" [i,dcy] 1 -- | Exponential decay (equvalent to $decay dcy - decay atk$). decay2 :: UGen -> UGen -> UGen -> UGen decay2 i atk dcy = mkFilter "Decay2" [i,atk,dcy] 1 -- | Single sample delay. delay1 :: UGen -> UGen delay1 i = mkFilter "Delay1" [i] 1 -- | Two sample delay. delay2 :: UGen -> UGen delay2 i = mkFilter "Delay2" [i] 1 -- | Simple delay line (cubic interpolation). delayC :: UGen -> UGen -> UGen -> UGen delayC i mt dly = mkFilter "DelayC" [i,mt,dly] 1 -- | Simple delay line (linear interpolation). delayL :: UGen -> UGen -> UGen -> UGen delayL i mt dly = mkFilter "DelayL" [i,mt,dly] 1 -- | Simple delay line (no interpolation). delayN :: UGen -> UGen -> UGen -> UGen delayN i mt dly = mkFilter "DelayN" [i,mt,dly] 1 -- | Tap a delay line from a DelTapWr UGen delTapRd :: UGen -> UGen -> UGen -> UGen -> UGen delTapRd buffer phase delTime interp = mkFilter "DelTapRd" [buffer,phase,delTime,interp] 1 -- | Write to a buffer for a DelTapRd UGen delTapWr :: Rate -> UGen -> UGen -> UGen delTapWr rate buffer in_ = mkOscR [AR,KR] rate "DelTapWr" [buffer,in_] 1 -- | Fold to range. fold :: UGen -> UGen -> UGen -> UGen fold i j k = mkFilter "Fold" [i,j,k] 1 -- | FOF like filter. formlet :: UGen -> UGen -> UGen -> UGen -> UGen formlet i f a d = mkFilter "Formlet" [i,f,a,d] 1 -- | First order filter section. fos :: UGen -> UGen -> UGen -> UGen -> UGen fos i a0 a1 b1 = mkFilter "FOS" [i,a0,a1,b1] 1 -- | A simple reverb. freeVerb :: UGen -> UGen -> UGen -> UGen -> UGen freeVerb i mx room damp = mkFilter "FreeVerb" [i,mx,room,damp] 1 -- | A simple reverb (two channel). freeVerb2 :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen freeVerb2 i1 i2 mx room damp = mkFilter "FreeVerb2" [i1,i2,mx,room,damp] 2 -- | Gate. gate :: UGen -> UGen -> UGen gate i t = mkFilter "Gate" [i,t] 1 -- | A less-simple reverb. gVerb :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen gVerb i rs rt d bw sp dl rl tl mrs = mkFilter "GVerb" [i,rs,rt,d,bw,sp,dl,rl,tl,mrs] 2 -- | Hash input values. hasher :: UGen -> UGen hasher i = mkFilter "Hasher" [i] 1 -- | Hilbert transform. hilbert :: UGen -> UGen hilbert i = mkFilter "Hilbert" [i] 2 -- | Highpass filter. hpf :: UGen -> UGen -> UGen hpf i f = mkFilter "HPF" [i,f] 1 -- | Two point difference filter. hpz1 :: UGen -> UGen hpz1 i = mkFilter "HPZ1" [i] 1 -- | Two zero fixed highpass filter. hpz2 :: UGen -> UGen hpz2 i = mkFilter "HPZ2" [i] 1 -- | Is signal within specified range. inRange :: UGen -> UGen -> UGen -> UGen inRange i lo hi = mkFilter "InRange" [i,lo,hi] 1 -- | Control to audio rate converter. k2A :: UGen -> UGen k2A i = mkOscR [AR] AR "K2A" [i] 1 -- | Fixed resonator filter bank. klank :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen klank i fs fp d s = mkFilterMCER [AR] "Klank" [i,fs,fp,d] s 1 -- | Format frequency, amplitude and decay time data as required for klank. klankSpec :: [UGen] -> [UGen] -> [UGen] -> UGen klankSpec f a dt = mce ((concat . transpose) [f,a,dt]) -- | Variant for non-UGen inputs. klankSpec' :: [Double] -> [Double] -> [Double] -> UGen klankSpec' f a dt = let u = map constant in klankSpec (u f) (u a) (u dt) -- | Variant of 'klankSpec' for 'MCE' inputs. klankSpec_mce :: UGen -> UGen -> UGen -> UGen klankSpec_mce f a dt = let m = mceChannels in klankSpec (m f) (m a) (m dt) -- | Simple averaging filter. lag :: UGen -> UGen -> UGen lag i t = mkFilter "Lag" [i,t] 1 -- | Nested lag filter. lag2 :: UGen -> UGen -> UGen lag2 i t = mkFilter "Lag2" [i,t] 1 -- | Twice nested lag filter. lag3 :: UGen -> UGen -> UGen lag3 i t = mkFilter "Lag3" [i,t] 1 -- | Lag variant with separate upward and downward times. lagUD :: UGen -> UGen -> UGen -> UGen lagUD i t1 t2 = mkFilter "LagUD" [i,t1,t2] 1 -- | Nested lag filter. lag2UD :: UGen -> UGen -> UGen -> UGen lag2UD i t1 t2 = mkFilter "Lag2UD" [i,t1,t2] 1 -- | Twice nested lag filter. lag3UD :: UGen -> UGen -> UGen -> UGen lag3UD i t1 t2 = mkFilter "Lag3UD" [i,t1,t2] 1 -- | Last value before chang above threshhold. lastValue :: UGen -> UGen -> UGen lastValue i t = mkFilter "LastValue" [i,t] 1 -- | Sample and hold. latch :: UGen -> UGen -> UGen latch i t = mkFilter "Latch" [i,t] 1 -- | Remove DC offset. leakDC :: UGen -> UGen -> UGen leakDC i coef = mkFilter "LeakDC" [i,coef] 1 -- | Limiter. limiter :: UGen -> UGen -> UGen -> UGen limiter i l d = mkFilter "Limiter" [i,l,d] 1 -- | Map from a linear range to an exponential range. linExp :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen linExp i sl sh dl dh = mkFilter "LinExp" [i,sl,sh,dl,dh] 1 -- | Lowpass filter. lpf :: UGen -> UGen -> UGen lpf i f = mkFilter "LPF" [i,f] 1 -- | Two point average filter. lpz1 :: UGen -> UGen lpz1 i = mkFilter "LPZ1" [i] 1 -- | Two zero fixed lowpass filter. lpz2 :: UGen -> UGen lpz2 i = mkFilter "LPZ2" [i] 1 -- | Masks off bits in the mantissa of signal. mantissaMask :: UGen -> UGen -> UGen mantissaMask i bits = mkFilter "MantissaMask" [i,bits] 1 -- | Median filter. median :: UGen -> UGen -> UGen median size i = mkFilter "Median" [size,i] 1 -- | Parametric filter. midEQ :: UGen -> UGen -> UGen -> UGen -> UGen midEQ i f rq db = mkFilter "MidEQ" [i,f,rq,db] 1 -- | Moog VCF implementation. moogFF :: UGen -> UGen -> UGen -> UGen -> UGen moogFF i f g r = mkFilter "MoogFF" [i,f,g,r] 1 -- | Most changed input. mostChange :: UGen -> UGen -> UGen mostChange a b = mkFilter "MostChange" [a,b] 1 -- | Multiply add ternary operator. mulAdd :: UGen -> UGen -> UGen -> UGen mulAdd s m a = mkFilter "MulAdd" [s,m,a] 1 -- | Normalizer (flattens dynamics). normalizer :: UGen -> UGen -> UGen -> UGen normalizer i l d = mkFilter "Normalizer" [i,l,d] 1 -- | One pole filter. onePole :: UGen -> UGen -> UGen onePole i coef = mkFilter "OnePole" [i,coef] 1 -- | One zero filter. oneZero :: UGen -> UGen -> UGen oneZero i coef = mkFilter "OneZero" [i,coef] 1 -- | Maximum value. peak :: UGen -> UGen -> UGen peak t r = mkFilter "Peak" [t,r] 1 -- | Simple time domain pitch shifter. pitchShift :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen pitchShift i w p d t = mkFilter "PitchShift" [i,w,p,d,t] 1 -- | Karplus-Strong synthesis. pluck :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen pluck i tr mdl dl dc coef = mkFilter "Pluck" [i,tr,mdl,dl,dc,coef] 1 -- | Trigger counter. pulseCount :: UGen -> UGen -> UGen pulseCount t r = mkFilter "PulseCount" [t,r] 1 -- | Pass every nth trigger. pulseDivider :: UGen -> UGen -> UGen -> UGen pulseDivider t factor start = mkFilter "PulseDivider" [t,factor,start] 1 -- | Linear lag. ramp :: UGen -> UGen -> UGen ramp i t = mkFilter "Ramp" [i,t] 1 -- | Resonant highpass filter. rhpf :: UGen -> UGen -> UGen -> UGen rhpf i freq rq = mkFilter "RHPF" [i,freq,rq] 1 -- | Resonant lowpass filter. rlpf :: UGen -> UGen -> UGen -> UGen rlpf i freq rq = mkFilter "RLPF" [i,freq,rq] 1 -- | Resonant filter. resonz :: UGen -> UGen -> UGen -> UGen resonz i freq bwr = mkFilter "Resonz" [i,freq,bwr] 1 -- | Ringing filter (equivalent to Resonz). ringz :: UGen -> UGen -> UGen -> UGen ringz i freq dcy = mkFilter "Ringz" [i,freq,dcy] 1 -- | Track maximum level. runningMax :: UGen -> UGen -> UGen runningMax i t = mkFilter "RunningMax" [i,t] 1 -- | Track minimum level. runningMin :: UGen -> UGen -> UGen runningMin i t = mkFilter "RunningMin" [i,t] 1 -- | Running sum. runningSum :: UGen -> UGen -> UGen runningSum i n = mkFilter "RunningSum" [i,n] 1 -- | Select output from array of inputs. select :: UGen -> UGen -> UGen select i a = mkFilterMCE "Select" [i] a 1 -- | Send a trigger message from the server back to the all registered clients. sendTrig :: UGen -> UGen -> UGen -> UGen sendTrig i k v = mkFilter "SendTrig" [i,k,v] 0 -- | Send a reply message from the server back to the all registered clients. sendReply :: UGen -> UGen -> String -> [UGen] -> UGen sendReply i k n v = let n' = map (fromIntegral . fromEnum) n s = fromIntegral (length n') in mkFilter "SendReply" ([i,k,s] ++ n' ++ v) 0 -- | Set-reset flip flop. setResetFF :: UGen -> UGen -> UGen setResetFF t r = mkFilter "SetResetFF" [t,r] 1 -- | Wave shaper. shaper :: UGen -> UGen -> UGen shaper b s = mkFilter "Shaper" [b,s] 1 -- | Remove transients and higher frequencies. slew :: UGen -> UGen -> UGen -> UGen slew i up dn = mkFilter "Slew" [i,up,dn] 1 -- | Second order filter section (biquad). sos :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen sos i a0 a1 a2 b1 b2 = mkFilter "SOS" [i,a0,a1,a2,b1,b2] 1 -- | Stepper pulse counter. stepper :: UGen -> UGen -> UGen -> UGen -> UGen -> UGen -> UGen stepper t r mn mx s v = mkFilter "Stepper" [t,r,mn,mx,s,v] 1 -- | Triggered linear ramp. sweep :: UGen -> UGen -> UGen sweep t r = mkFilter "Sweep" [t,r] 1 -- | Control rate trigger to audio rate trigger converter t2A :: UGen -> UGen -> UGen t2A i offset = mkOscR [AR] AR "T2A" [i,offset] 1 -- | Audio rate trigger to control rate trigger converter t2K :: UGen -> UGen t2K i = mkOscR [KR] KR "T2K" [i] 1 -- | Delay trigger by specified interval. tDelay :: UGen -> UGen -> UGen tDelay i d = mkFilter "TDelay" [i,d] 1 -- | Time since last triggered. timer :: UGen -> UGen timer t = mkFilter "Timer" [t] 1 -- | Toggle flip flop. toggleFF :: UGen -> UGen toggleFF t = mkFilter "ToggleFF" [t] 1 -- | When triggered output trigger for specified duration. trig :: UGen -> UGen -> UGen trig i d = mkFilter "Trig" [i,d] 1 -- | When triggered output unit signal for specified duration. trig1 :: UGen -> UGen -> UGen trig1 i d = mkFilter "Trig1" [i,d] 1 -- | Two pole filter. twoPole :: UGen -> UGen -> UGen -> UGen twoPole i freq radius = mkFilter "TwoPole" [i,freq,radius] 1 -- | Two zero filter. twoZero :: UGen -> UGen -> UGen -> UGen twoZero i freq radius = mkFilter "TwoZero" [i,freq,radius] 1 -- | Variable shaped lag. varLag :: UGen -> UGen -> UGen -> UGen varLag i t s = mkFilter "VarLag" [i,t,s] 1 -- | Wrap to range. wrap :: UGen -> UGen -> UGen -> UGen wrap i j k = mkFilter "Wrap" [i,j,k] 1 -- | Index into a table with a signal. wrapIndex :: UGen -> UGen -> UGen wrapIndex b i = mkFilter "WrapIndex" [b,i] 1 -- * BEQ filters -- | Bi-quad low-pass filter. bLowPass :: UGen -> UGen -> UGen -> UGen bLowPass i f rq = mkFilter "BLowPass" [i,f,rq] 1 -- | Bi-quad high-pass filter. bHiPass :: UGen -> UGen -> UGen -> UGen bHiPass i f rq = mkFilter "BHiPass" [i,f,rq] 1 -- | Bi-quad all-pass filter. bAllPass :: UGen -> UGen -> UGen -> UGen bAllPass i f rq = mkFilter "BAllPass" [i,f,rq] 1 -- | Bi-quad band-pass filter. bBandPass :: UGen -> UGen -> UGen -> UGen bBandPass i f bw = mkFilter "BBandPass" [i,f,bw] 1 -- | Bi-quad band-stop filter. bBandStop :: UGen -> UGen -> UGen -> UGen bBandStop i f bw = mkFilter "BBandStop" [i,f,bw] 1 -- | Bi-quad peak equaliser. bPeakEQ :: UGen -> UGen -> UGen -> UGen -> UGen bPeakEQ i f rq db = mkFilter "BPeakEQ" [i,f,rq,db] 1 -- | Bi-quad low shelf filter. bLowShelf :: UGen -> UGen -> UGen -> UGen -> UGen bLowShelf i f rs db = mkFilter "BLowShelf" [i,f,rs,db] 1 -- | Bi-quad high shelf filter. bHiShelf :: UGen -> UGen -> UGen -> UGen -> UGen bHiShelf i f rs db = mkFilter "BHiShelf" [i,f,rs,db] 1 -- | Calculate coefficients for bi-quad low pass filter. bLowPassCoef :: Floating a => a -> a -> a -> (a,a,a,a,a) bLowPassCoef sr freq rq = let w0 = pi * 2 * freq * (1 / sr) cos_w0 = cos w0 i = 1 - cos_w0 alpha = sin w0 * 0.5 * rq b0rz = recip (1 + alpha) a0 = i * 0.5 * b0rz a1 = i * b0rz b1 = cos_w0 * 2 * b0rz b2 = (1 - alpha) * negate b0rz in (a0,a1,a0,b1,b2)