Main Page       Index


sah.lsp


 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

 (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


View the Sourcecode :



;; 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)))))))


Main Page       Index