CCRMA

moog.lisp: a virtual analog 24dB/oct lowpass filter

original C code by Tim Stilson
translated into clm by Fernando Lopez-Lezcano

moog.lisp is a translation into lisp and clm of Tim Stilson's implementation of a virtual analog Moog-style 24dB/octave lowpass filter. As the original analog filter it features nearly constant Q with changes in the cutoff frequency and can be driven into oscillation by large values of Q's. Both frequency and Q are easily settable and they can be changed dynamically (see the example below). Complete details on its implementation can be found in TimStilson's Papers web page (in both postcript and Acrobat formats).

MOOG-FILTER

  make-moog-filter &optional-key (frequency 440) (Q 0.9)
  moog-filter m sig

make-moog-filter creates a moog filter with a given cutoff frequency and Q (resonance). Q's close to 1 will make the filter oscillate. Currently the resulting sine wave is not clean because of the abrupt characteristics of the digital saturation transfer function.

moog-filter runs an input signal through a particular instance of a moog filter.

Note: the so called cutoff frequency is not really the -3dB point of the lowpass filter, but rather the frequency of its resonant peak. It was actually easier to measure in a hurry than the real cutoff frequency.

Examples

filter-noise.ins is a small demonstration instrument that filters white noise. It features envelope control of both filter cutoff frequency (freq-env) and resonance or Q (res-env). Here's the instrument:

(definstrument filter-noise (start-time duration amp 
					&key
					(noise-freq 10000)
					(freq-env '(0 -1 1 1))
					(res-env '(0 0 1 1)))
  (multiple-value-bind (beg end)
      (get-beg-end start-time duration)
    (let* ((fenv (make-env :envelope freq-env
			   :start-time start-time
			   :duration duration))
	   (qenv (make-env :envelope res-env
			   :start-time start-time
			   :duration duration))
	   (f (make-moog-filter :frequency 0
				:Q 0.9))
	   (noi (make-randi :frequency noise-freq :amplitude amp)))
      (Run
       (loop for i from beg to end do
	     (setf (moog-Q f)(env qenv)
		   (moog-frequency f)(env fenv))
	     (outa i (moog-filter f (randi noi))))))))

Here's a simple with-sound that creates the quintaessential resonante filter sweep:

(with-sound(:statistics t :sndfile "/zap/test.snd" :srate 44100)
  (filter-noise 0 5 0.041 
		:res-env '(0 0.94 1 0.94) 
		:freq-env '(0 50 1 22050) 
		:noise-freq 22050))


©1998 Fernando Lopez-Lezcano. All Rights Reserved.
Created and mantained by Fernando Lopez-Lezcano, nando@ccrma.stanford.edu