sah.lsp Version 1.00 31 October 2004 Author Steven Jones Contact jones57@swbell.net include the word "nyquist" in subject line The contents of this file are released under the terms of the GNU General Public License. See the file LICENSE.txt A sample and hold simulation. For a more-efficient simulation of sample and hold of noise source, see psah.lsp
function
(sah frq [:dur][:src][:holdfn][:sr])
Sample and hold
frq - Flonum. Sample clock frequency in Hz.
:dur - Flonum. Duration of result in seconds. If dur is greater then
duration of source signal the sampling wraps around to the start
of the source as needed. Default 1 sec.
:src - Sound. The source signal, default noise.
:holdfn - Closure. The hold function is used to maintain the current output
level until the next sample period. The default function, rgate,
maintains a static amplitude over its duration for a rectangular
contours. The lambda form of holdfn must conform to
(lambda (period a1 a2)...) and return a sound.
The arguments are:
period - The duration to hold output
a1 - The amplitude of this sample
a2 - The amplitude of the previous sample
Other interesting functions provide a "leaky" or slew limited
output
(lambda (period a1 &optional dummy)(scale a1 (percussion period)))
(lambda (period a1 a2)(segment a1 period a2))
:sr - Integer. The sample rate of the result, default *control-srate*.
return - Sound. The result is a dur second sound at sample rate sr
;; sah.lsp
;; Version 1.00 31 October 2004
;; Author Steven Jones
;;
;; Contact jones57@swbell.net include the word "nyquist" in subject line
;;
;; The contents of this file are released under the terms of the GNU General
;; Public License. See the file LICENSE.txt
;;
;; A sample and hold simulation. For a more-efficient simulation of sample and
;; hold of noise source, see psah.lsp
;;
(provide 'sah)
(current-file "sah")
;; @doc function sah
;; (sah frq [:dur][:src][:holdfn][:sr])
;; Sample and hold
;;
;; frq - Flonum. Sample clock frequency in Hz.
;; :dur - Flonum. Duration of result in seconds. If dur is greater then
;; duration of source signal the sampling wraps around to the start
;; of the source as needed. Default 1 sec.
;; :src - Sound. The source signal, default noise.
;;
;; :holdfn - Closure. The hold function is used to maintain the current output
;; level until the next sample period. The default function, rgate,
;; maintains a static amplitude over its duration for a rectangular
;; contours. The lambda form of holdfn must conform to
;;
;; (lambda (period a1 a2)...) and return a sound.
;;
;; The arguments are:
;; period - The duration to hold output
;; a1 - The amplitude of this sample
;; a2 - The amplitude of the previous sample
;;
;; Other interesting functions provide a "leaky" or slew limited
;; output
;;
;; (lambda (period a1 &optional dummy)(scale a1 (percussion period)))
;;
;; (lambda (period a1 a2)(segment a1 period a2))
;;
;;
;; :sr - Integer. The sample rate of the result, default *control-srate*.
;;
;; return - Sound. The result is a dur second sound at sample rate sr
;;
(defun sah (frq &key (dur 1) src (holdfn #'rgate)(sr *control-srate*))
(let (period s*period periods clone sam last-sam refresh-fn)
(setq src (force-srate sr (or src (noise dur))))
(setq period (/ 1.0 frq))
(setq s*period (truncate (* period sr))) ;Sample words per period
(setq periods (truncate (/ dur period))) ;Number of periods
;; refresh-fn performs the following functions
;; Save current sample value to last-sam
;; Update sam by reading next sample from clone of source signal
;; If sam is null, indicating we have reached end of clone, create a new
;; copy of source signal and assign it to clone, try assigning sam again.
(setq refresh-fn #'(lambda ()
(setq last-sam sam)
(setq sam (snd-fetch clone))
(if (null sam)
(progn
(setq clone (snd-copy src))
(setq sam (snd-fetch clone))))))
(setq clone (snd-copy src))
(force-srate sr
(seqrep (i periods)
(prog2
(funcall refresh-fn)
(funcall holdfn period sam last-sam)
(dotimes (i (1- s*period))
(funcall refresh-fn)))))))