[Moderator note: Topic split from http://forum.audacityteam.org/viewtopic.php?p=186807#p186807 ]
Yes, and my language is sometimes teribly faulty too.
Anyway, here’s some code that excessively uses the “convolve”-function. Its fun to play with. the Kernel-function is loosely based on a basic listing from chapter 16 in Steven W. Smith’s book
The Scientist and Engineer’s Guide to
Digital Signal Processing
http://www.dspguide.com/ch16.htm
There could a lot of other window-functions be implemented, and with dtf, the calculation time will be 100 times faster.
Apropos terrible slowness, is there any way to measure the speed of a code execution? a System function or variable, that can be read out? That’s maybe something for the Nyquist-Xmas-wishlist.
(set-sound-srate *sound-srate*); reset environment
;; Converts a list into a sound
;; Either a list or the unquoted sample-values can be given
(defun s-list (samplerate &rest args)
(let*
((samples (if (listp (car args))
(car args) args))
(vec (eval (read (make-string-input-stream (format NIL "#~a" samples))))))
(snd-from-array 0 samplerate vec)))
;;
;; returns a filter-kernel of length m (+1) for convolution
;; m (even) determinates the roll-off quality and behaviour.
;; f-cut is the cut-off-frequency from 0.0 to 0.5
;; where 0.5 is half the sample-rate (e. g. 22050 hz)
;; If :Hp is true, the filter is highpass, otherwise lowpass.
(defun kernel (f-cut m &key hp (win t) &aux h-t i (sum 0))
(setq m (* (truncate (/ m 2)) 2))
(dotimes (cnt (1+ m))
(setq i (float cnt))
(if (= (- i (/ m 2)) 0)
(setf h-t (cons
(* 2 pi f-cut
;; multiply with Hamming-window or 1 (=square)
(if win (- 0.54 (* 0.46 (cos (/ (* 2 pi i) m)))) 1.0)) h-t))
(setf h-t (cons
(* (/ (sin (* 2 pi f-cut (- i (/ m 2)))) (- i (/ m 2)))
;; multiply with Hamming-window or 1 (=square)
(if win (- 0.54 (* 0.46 (cos (/ (* 2 pi i) m)))) 1.0)) h-t)))
(setf sum (+ sum (car h-t))))
;; normalize so that the sum is 1 (LP) or 0 (HP)
(if hp
(progn (setq sum (- sum))
(setf (nth (truncate (/ m 2)) h-t )
(+ (nth (truncate (/ m 2)) h-t) sum))
nil)); nothing to return from progn
;; increase temporarily precision for conversion
(progv '(*float-format*) '("%#.21f")
;(print sum)
;(print (nth (truncate (/ m 2)) h-t))
(mult (/ sum)(s-list 44100 h-t))))
;;
;; test our code
(setf sig (mult 0.1 (noise 1.5)))
(setq k-len 750)
(setq freq 1320)
(setq cutoff (* freq (/ *sound-srate*)))
(setf LP (kernel cutoff k-len ))
(setf HP (kernel cutoff k-len :hp t ))
(setf BP (convolve LP HP))
(setq norm (/ 0.3 (peak bp ny:all)))
(setf BP-sq (convolve (kernel cutoff k-len :win nil) (kernel cutoff k-len :hp t :win nil)))
(setf norm2 (/ 0.3 (peak bp-sq ny:all)))
(seq
sig
(convolve sig LP); Lowpass
(convolve sig hp); Highpass
(mult norm2 (convolve sig bp-sq)); Bandpass & square-window
(mult norm (convolve sig bp)); Bandpass & hamming-window
;;; "abuses" convolution as a correlation at *control-srate*
(mult 0.1 (convolve sig (lfo (/ freq 20))))
(stretch 1.5 (mult 0.2 (hzosc freq)))); control tone