Main Page       Index


utilities.lsp


 utilities.lsp
 Version 1.01 02 Jun 2005, Removed several never-used functions.
 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

 General utility functions


function

tl

 (tl)
 An alias for top-level


function

ann

 (ann)
 An alias for (auotnorm-on)


function

anf

 (anf)
 An alias for (autonorm-off)


macro

?

 (? obj)
 Combination of args and grindef
 Prints list of arguments to and lambda expression of obj

 obj   - closure


function

current-file

 (current-file file)
 Set *current-file* to file. The current file is used in conjunction with
 the rl function to quickly reload a file under development.

 file - string. 


function

errload

 (errload file)
 Load lisp file with error check. If file can not be loaded an error is
 produced.

 file - string


function

rl

 (rl)
 Reload the "current-file" 


function

load-list

 (load-list lst)
 Load list of lisp files.
 
 lst - List of strings


function

rla

 (rla)
 Reload all files in *modules*. Typically files are appended to *modules* by
 the provide function


function

list-packages

 (list-packages)
 List the files in *modules*


function

nice-load

 (nice-load file)
 Load file without changing the current file
 
 file - string


function

is-loaded-p

 (is-loaded-p sym)
 Determine if package represented by symbol has been loaded. Specifically
 check to see if *modules* contains the symbol sym

 sym    - symbol.
 return - bool.


function

provide

 (provide sym)
 Add symbol sym to *modules* list indicating a specific package has
 been loaded. Provide is used in conjunction with require

 sym - symbol. The package name


function

require

 (require sym [filelist])
 Conditionally load file(s) 
 
 sym      - symbol. A symbol representing package name. If a symbol by the
            same name is a member of *modules* no further action is taken.
            If *modules* does not contain sym an attempt is made to
            load one or more files. If any one of the loaded files calls
            provide with sym as an argument, then future calls to 
            (require sym) will be ignored, preventing redundant file
            loading.  If the optional filelist argument is not specified the
            filename is derived from the symbol name of sym. One consequent
            of using the symbol name is that filenames
            MUST NOT CONTAIN UPPER CASE CHARACTERS.

 filelist - symbol, string, list. If filelist is not specified the filename
            is derived from the symbol name of sym. If filelist is
            specified it may take one of three forms.

            filelist may be a symbol. In this case the symbol name is
            converted to a lower case string and used as the filename.

            filelist may also be a string. In the case of a string the
            value of filelist is used directly as the filename, mixed case 
            names are possible.

            filelist may be a list of strings. In this case ALL files in 
            filelist are loaded, mixed case names are allowed.


function

here

 (here [a [b [c ...]]])
 Debug aid used to trace execution. Prints the word "HERE" followed by its
 arguments

 a, b, c - any.


function

min-control-time

 (min-control-time)

 return - flonum, The minimum time, in seconds, resolvable at the current
          control sample rate


function

min-sample-time

 (min-sample-time)

 return - flonum, The minimum time, in seconds, resolvable at the current
          audio sample rate


function

msound

 (msound snd)
 Multi-channel version of sound

 snd    - sound or array of sounds
 return - sound or array of sounds


function

->vector

 (->vector obj [dim])
 Convert obj to vector. 

 obj    - any. If obj is a vector it is returned directly, the dim argument
          is ignored. If obj is any non-vector object, a vector of dimension
          dim is created and filled with dim copies of obj.

 dim    - integer. The number of elements of the resulting vector. 
          The dim value is ignored if obj is an vector to start with. 
          Default 2

 return - vector


function

->mono

 (->mono obj)
 Convert sound(s) to mono.
 
 obj    - sound, vector or list of sounds. If obj is a simple sound object it
          is returned directly. If obj is either a vector or list of sounds, 
          the sound elements are mixed to a single sound object.

 return - sound.


function

invert

 (invert sig)
 Perform amplitude inversion of signal

 sig    - sound
 return - sound with the same sample rate as signal.


function

phase

 (phase [n])
 Used to provide the phase argument to osc, fmosc etc.

 n      - any. If n is nil the result is 0.
          if n is any number, the returned value is that number
          if n is non-numeric and true (not nil) the result is a random 
          integer between 0 and 359

 return - flonum or integer


function

idfn

 (idfn arg)
 An identity function simply returns its argument.

 arg    - any.
 return - any.


function

vector->list

 (vector->list vec)
 Convert vector to list


function

list->vector

 (list->vector)
 Convert list to vector


function

zip

 (zip  lst1 lst2)
 Create new list by taking alternate elements from source list
 (zip '(a b c) '(1 2 3)) --> (a 1 b 2 c 3)

 lst1   - list
 lst2   - list
 return - list. The length of the result is the same as the shortest
          argument list


function

butlast

 (butlast lst)
 (butlast '(a b c d)) --> (a b c)
 lst    - list
 return - list. Return all but the final list node of lst


function

group

 (group lst)
 Group elements of list into sub-list
 (group '(a b c d)) --> ((a b)(c d))
 
 lst    - list
 return - list


function

rotate

 (rotate lst [n [fn]])
 Apply function fn to final list element and rotate it to front of list

 lst    - list 
 n      - integer. Number of elements to rotate, default 1
 fn     - closure. The function applied to the rotated elements. The function
          should take a single element.
 return - list


function

-rotate

 (-rotate lst [n [fn]])
 Same as rotate but in opposite direction.


function

flatten

 (flatten lst)
 Remove list sub-list
 (flatten '(a (b (c (d))))) --> (a b c d)
 
 lst    - list
 return - list


function

nflatten

 (nflatten lst n)
 Same as flatten but only descend n levels
 (nflatten '(a (b (c (d (e))))) 2) --> (a b c (d (e)))

 lst    - list
 n      - integer
 return - list


function

flatten-sublist

 (flatten-sublist lst)
 (flatten-sublist '(a b (c)(d (e f)))) --> ((a)(b)(c)(d e f))

 lst    - list
 return - list


function

nest

 (nest lst)
 Replace every element of a list by a list containing it.
 (nest '(a b c d)) --> ((a)(b)(c)(d))
 
 lst    - list
 return - list


function

locate

 (locate lst obj [:test])
 Return least index of obj in list.

 lst    - list
 obj    - any. Object to test
 :test  - closure. The equality test, default #'eq
 return - integer. If obj is not an element of lst return nil


function

->list

 (->list obj)
 Convert object to list

 obj    - any
 return - list. If obj is a list it is returned directly, otherwise embed obj
          in a list and return


function

copies

 (copies [n [obj])
 Create list of n copies of obj

 n      - integer, default 1
 obj    - any
 return - list


function

sublist-extract

 (sublist-extract lst n)
 Build list consisting of the nth element of each sublist of lst.
 (sublist-extract '((q w e)(a s d)(z x c)) 1) --> (w s x)
 
 lst    - list
 n      - integer
 return - list


function

eliminate-duplicates

 (eliminate-duplicates  lst [:test])
 Construct new list which contains only the unique elements of lst

 lst    - list
 :test  - closure, default #'eq
 return - list


function

get-keyword-value

 (get-keyword-value keysym arglist [default])
 Return value -after- keysym in the list. Typically used to parse keywords
 from argument list created by &rest

 (get-keyword-value '(a b c :ape 1 :bat 2) ':ape) --> 1

 keysym  - symbol
 arglist - list
 default - any. The default value if arglist does not contain keysym
 return  - any


function

require-keyword

 (require-keyword keysym arglist [message])
 Like get-keyword-symbol but produces a warning message
 if keysym is not a member of arglist

 keysym  - symbol. The key symbol 

 arg     - list. The list of keyword/value pairs arguments.

 message - string. Additional error message text
 
 return  - any.


function

every-odd

 (every-odd lst)
 Generate new list consisting of only the odd numbered elements of argument
 list
 
 lst    - list.
 return - list.


function

every-even

 (every-even lst)
 Generate new list consisting of only the even numbered elements 
 of argument list

 lst    - list
 return - list


function

fifth

 (fifth lst)

 lst    - list
 return - any. The fifth element of lst


function

sixth

 (sixth lst)

 lst    - list
 return - any. The sixth element of lst


View the Sourcecode :



;; utilities.lsp
;; Version 1.01 02 Jun 2005, Removed several never-used functions.
;; 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
;;
;; General utility functions
;;

;; ************************************************************************** 
;;		A few functions for convenient interactive use
;; ************************************************************************** 

;; @doc function tl
;; (tl)
;; An alias for top-level
;;

(setfn tl top-level)


;; @doc function ann
;; (ann)
;; An alias for (auotnorm-on)
;;

(setfn ann autonorm-on)


;;@doc function anf
;; (anf)
;; An alias for (autonorm-off)
;;

(setfn anf autonorm-off)


;; @doc macro ?
;; (? obj)
;; Combination of args and grindef
;; Prints list of arguments to and lambda expression of obj
;;
;; obj   - closure
;;

(defmacro ? (obj)
  `(progn (args ',obj)
	  (grindef ',obj)))


;; ************************************************************************** 
;;			     Lisp File Management
;; ************************************************************************** 

;; @doc function current-file
;; (current-file file)
;; Set *current-file* to file. The current file is used in conjunction with
;; the rl function to quickly reload a file under development.
;;
;; file - string. 
;;

(defun current-file (file)
  (setq *current-file* file))


(current-file "utilities")


;; @doc function errload
;; (errload file)
;; Load lisp file with error check. If file can not be loaded an error is
;; produced.
;;
;; file - string
;;

(defun errload (file)
  (gc-reset)
  (format t "~%")
  (if (not (load file))
      (error (format nil "Could not load file ~s~%" file))))


;; @doc function rl
;; (rl)
;; Reload the "current-file" 
;;

(defun rl ()
  (format t "~%reloading ~s~%" *current-file*)
  (errload *current-file*))


;; @doc function load-list
;; (load-list lst)
;; Load list of lisp files.
;; 
;; lst - List of strings
;;

(defun load-list (lst)
  (if lst
      (progn 
	(format t "loading ~s~%" (car lst))
	(errload (car lst))
	(load-list (cdr lst)))
    (format t "DONE~%")))


;; @doc function rla
;; (rla)
;; Reload all files in *modules*. Typically files are appended to *modules* by
;; the provide function
;;

(defun rla ()
  (dotimes (n (length *modules*))
    (let ((file (string-downcase (symbol-name (nth n (reverse *modules*))))))
      (errload file))))


;; @doc function list-packages
;; (list-packages)
;; List the files in *modules*
;;

(defun list-packages (&optional (lst *modules*))
  (if lst
      (progn 
	(format t "~A~%" (car lst))
	(list-packages (cdr lst)))))


;; @doc function nice-load
;; (nice-load file)
;; Load file without changing the current file
;; 
;; file - string
;; 

(defun nice-load (file)
  (let ((temp *current-file*)
	(rs nil))
    (setq rs (errload file))
    (setq *current-file* temp)
    rs))


;; @doc function is-loaded-p
;; (is-loaded-p sym)
;; Determine if package represented by symbol has been loaded. Specifically
;; check to see if *modules* contains the symbol sym
;;
;; sym    - symbol.
;; return - bool.
;;

(defun is-loaded-p (sym)
  (member sym *modules* :test #'eq))


;; @doc function provide
;; (provide sym)
;; Add symbol sym to *modules* list indicating a specific package has
;; been loaded. Provide is used in conjunction with require
;;
;; sym - symbol. The package name
;;

(defun provide (sym)
  (if (not (is-loaded-p sym))
       (setq *modules* (cons sym *modules*))))


;; @doc function require
;; (require sym [filelist])
;; Conditionally load file(s) 
;; 
;; sym      - symbol. A symbol representing package name. If a symbol by the
;;            same name is a member of *modules* no further action is taken.
;;            If *modules* does not contain sym an attempt is made to
;;            load one or more files. If any one of the loaded files calls
;;            provide with sym as an argument, then future calls to 
;;            (require sym) will be ignored, preventing redundant file
;;            loading.  If the optional filelist argument is not specified the
;;            filename is derived from the symbol name of sym. One consequent
;;            of using the symbol name is that filenames
;;            MUST NOT CONTAIN UPPER CASE CHARACTERS.
;;
;; filelist - symbol, string, list. If filelist is not specified the filename
;;            is derived from the symbol name of sym. If filelist is
;;            specified it may take one of three forms.
;;
;;            filelist may be a symbol. In this case the symbol name is
;;            converted to a lower case string and used as the filename.
;;
;;            filelist may also be a string. In the case of a string the
;;            value of filelist is used directly as the filename, mixed case 
;;            names are possible.
;;
;;            filelist may be a list of strings. In this case ALL files in 
;;            filelist are loaded, mixed case names are allowed.
;;

(defun require (sym &optional filelist)
  (if (not (member sym *modules*))
      (cond ((null filelist)
	     (errload (string-downcase (symbol-name sym))))
	    ((listp filelist)
	     (dotimes (n (length filelist))
	       (errload (nth n filelist))))
	    ((stringp filelist)
	     (errload filelist))
	    (t (errload (string-downcase (symbol-name filelist)))))))


;; @doc function here
;; (here [a [b [c ...]]])
;; Debug aid used to trace execution. Prints the word "HERE" followed by its
;; arguments
;;
;; a, b, c - any.
;;

(defun here (&rest args)
  (format t "HERE ")
  (do ((index 0 (+ index 1)))
      ((> index (- (length args) 1)))
    (format t "~s " (nth index args)))
  (format t "~%"))


;; ************************************************************************** 
;;		       Basic signal and sound functions
;; ************************************************************************** 

;; @doc function min-control-time
;; (min-control-time)
;;
;; return - flonum, The minimum time, in seconds, resolvable at the current
;;          control sample rate
;;

(defun min-control-time ()
  (/ (float *control-srate*)))


;; @doc function min-sample-time
;; (min-sample-time)
;;
;; return - flonum, The minimum time, in seconds, resolvable at the current
;;          audio sample rate
;;

(defun min-audio-time ()
  (/ (float *sound-srate*)))


;; @doc function msound
;; (msound snd)
;; Multi-channel version of sound
;;
;; snd    - sound or array of sounds
;; return - sound or array of sounds
;;

(defun msound (snd)
  (multichan-expand #'sound snd))


;; @doc function ->vector
;; (->vector obj [dim])
;; Convert obj to vector. 
;;
;; obj    - any. If obj is a vector it is returned directly, the dim argument
;;          is ignored. If obj is any non-vector object, a vector of dimension
;;          dim is created and filled with dim copies of obj.
;;
;; dim    - integer. The number of elements of the resulting vector. 
;;          The dim value is ignored if obj is an vector to start with. 
;;          Default 2
;;
;; return - vector
;;

(defun ->vector (obj &optional (dim 2))
  (if (arrayp obj)
      obj
    (let ((arr (make-array dim)))
      (dotimes (i dim)
	(setf (aref arr i) obj))
      arr)))


;; @doc function ->mono
;; (->mono obj)
;; Convert sound(s) to mono.
;; 
;; obj    - sound, vector or list of sounds. If obj is a simple sound object it
;;          is returned directly. If obj is either a vector or list of sounds, 
;;          the sound elements are mixed to a single sound object.
;;
;; return - sound.
;;

(defun ->mono (obj)
  (cond ((soundp obj) obj)
	((arrayp obj)
	 (simrep (i (length obj))(aref obj i)))
	((listp obj)
	 (simrep (i (length obj))(nth i obj)))
	(t (error (format nil "->mono bad argument type ~a" obj)))))


;; @doc function invert
;; (invert sig)
;; Perform amplitude inversion of signal
;;
;; sig    - sound
;; return - sound with the same sample rate as signal.
;;

(defun invert (sig)(scale -1 sig))


;; @doc function phase
;; (phase [n])
;; Used to provide the phase argument to osc, fmosc etc.
;;
;; n      - any. If n is nil the result is 0.
;;          if n is any number, the returned value is that number
;;          if n is non-numeric and true (not nil) the result is a random 
;;          integer between 0 and 359
;;
;; return - flonum or integer
;;

(defun phase (&optional n)
  (cond ((null n) 0)
	((numberp n) n)
	(t (random 360))))


;; @doc function idfn
;; (idfn arg)
;; An identity function simply returns its argument.
;;
;; arg    - any.
;; return - any.
;;

(defun idfn (arg) arg)


;; ************************************************************************** 
;;				List Functions
;; ************************************************************************** 

;; @doc function vector->list
;; (vector->list vec)
;; Convert vector to list
;;

(defun vector->list (vec)
  (do ((i 0 (+ i 1))(acc '()(cons (aref vec i) acc)))
      ((= i (length vec))(reverse acc))))


;; @doc function list->vector
;; (list->vector)
;; Convert list to vector
;;

(defun list->vector (lst)
  (do ((I 0 (+ i 1))(acc (make-array (length lst))))
      ((= i (length acc)) acc)
    (setf (aref acc i)(nth i lst))))


;; @doc function zip
;; (zip  lst1 lst2)
;; Create new list by taking alternate elements from source list
;; (zip '(a b c) '(1 2 3)) --> (a 1 b 2 c 3)
;;
;; lst1   - list
;; lst2   - list
;; return - list. The length of the result is the same as the shortest
;;          argument list
;;

(defun zip (lst1 lst2)
  (if (or (null lst1)(null lst2))
      nil
    (cons (car lst1)
	  (cons (car lst2)
		(zip (cdr lst1)(cdr lst2))))))


;; @doc function butlast
;; (butlast lst)
;; (butlast '(a b c d)) --> (a b c)
;; lst    - list
;; return - list. Return all but the final list node of lst
;;

(defun butlast (lst)
  (reverse (cdr (reverse lst))))


;; @doc function group
;; (group lst)
;; Group elements of list into sub-list
;; (group '(a b c d)) --> ((a b)(c d))
;; 
;; lst    - list
;; return - list
;;

(defun group (lst)
  (if lst
      (cons (list (car lst)(second lst))(group (cdr (cdr lst))))
    nil))


;; @doc function rotate
;; (rotate lst [n [fn]])
;; Apply function fn to final list element and rotate it to front of list
;;
;; lst    - list 
;; n      - integer. Number of elements to rotate, default 1
;; fn     - closure. The function applied to the rotated elements. The function
;;          should take a single element.
;; return - list
;;

(defun rotate (lst &optional (n 1)(fn #'idfn))
  (if (<= n 0)
      lst
    (rotate (cons (funcall fn (car (last lst)))(butlast lst))(- n 1) fn)))


;; @doc function -rotate
;; (-rotate lst [n [fn]])
;; Same as rotate but in opposite direction.
;;

(defun -rotate (lst &optional (n 1)(fn #'idfn))
  (if (<= n 0)
      lst
    (-rotate (reverse (cons (funcall fn (car lst))(reverse (cdr lst))))(- n 1) fn)))


;; @doc function flatten
;; (flatten lst)
;; Remove list sub-list
;; (flatten '(a (b (c (d))))) --> (a b c d)
;; 
;; lst    - list
;; return - list
;;

(defun flatten (lst)
   (cond ((null lst) nil)
	((atom lst)(list lst))
	(t (append (flatten (car lst))
		   (flatten (cdr lst))))))


;; @doc function nflatten 
;; (nflatten lst n)
;; Same as flatten but only descend n levels
;; (nflatten '(a (b (c (d (e))))) 2) --> (a b c (d (e)))
;;
;; lst    - list
;; n      - integer
;; return - list
;;

(defun nflatten (lst n)
  (cond ((null lst) nil)
	((atom lst)(list lst))
	(t (if (plusp n)
	       (append (nflatten (car lst) (- n 1))
		       (nflatten (cdr lst) n))
	     (cons (car lst)
		     (nflatten (cdr lst) n))))))


;; @doc function flatten-sublist 
;; (flatten-sublist lst)
;; (flatten-sublist '(a b (c)(d (e f)))) --> ((a)(b)(c)(d e f))
;;
;; lst    - list
;; return - list
;;

(defun flatten-sublist (lst)
  (if lst
      (cons (flatten (car lst))(flatten-sublist (cdr lst)))
    nil))


;; @doc function nest
;; (nest lst)
;; Replace every element of a list by a list containing it.
;; (nest '(a b c d)) --> ((a)(b)(c)(d))
;; 
;; lst    - list
;; return - list
;;

(defun nest (lst)
  (if (null lst)
      nil
    (cons (list (car lst))(nest (cdr lst)))))


;; @doc function locate
;; (locate lst obj [:test])
;; Return least index of obj in list.
;;
;; lst    - list
;; obj    - any. Object to test
;; :test  - closure. The equality test, default #'eq
;; return - integer. If obj is not an element of lst return nil
;;

(defun locate (lst obj &key (test #'eq))
  (let ((rs (member obj lst :test test)))
    (if (null rs)
	'NIL
      (- (length lst)(length rs)))))


;; @doc function ->list
;; (->list obj)
;; Convert object to list
;;
;; obj    - any
;; return - list. If obj is a list it is returned directly, otherwise embed obj
;;          in a list and return
;;

(defun ->list  (obj)
  (if (listp obj) obj (list obj)))


;; @doc function copies 
;; (copies [n [obj])
;; Create list of n copies of obj
;;
;; n      - integer, default 1
;; obj    - any
;; return - list
;;

(defun copies (&optional (n 1)(obj nil))
  (if (plusp n)
      (cons obj (copies (- n 1) obj))
    nil))


;; @doc function sublist-extract
;; (sublist-extract lst n)
;; Build list consisting of the nth element of each sublist of lst.
;; (sublist-extract '((q w e)(a s d)(z x c)) 1) --> (w s x)
;; 
;; lst    - list
;; n      - integer
;; return - list
;;

(defun sublist-extract (lst n)
  (if (null lst)
      nil
    (cons (nth n (car lst))(sublist-extract (cdr lst) n))))


;; @doc function eliminate-duplicates
;; (eliminate-duplicates  lst [:test])
;; Construct new list which contains only the unique elements of lst
;;
;; lst    - list
;; :test  - closure, default #'eq
;; return - list
;;

(defun eliminate-duplicates (lst &key (test #'eq))
  (let ((acc '()))
    (dolist (e lst)
      (if (not (member e acc :test test))
	  (setf acc (cons e acc))))
    (reverse acc)))


;; @doc function get-keyword-value
;; (get-keyword-value keysym arglist [default])
;; Return value -after- keysym in the list. Typically used to parse keywords
;; from argument list created by &rest
;;
;; (get-keyword-value '(a b c :ape 1 :bat 2) ':ape) --> 1
;;
;; keysym  - symbol
;; arglist - list
;; default - any. The default value if arglist does not contain keysym
;; return  - any
;;

(defun get-keyword-value (keysym arglist &optional default)
  (let ((sublist (member keysym arglist)))
    (if sublist (or (car (cdr sublist)) default)
      default)))


;; @doc function require-keyword
;; (require-keyword keysym arglist [message])
;; Like get-keyword-symbol but produces a warning message
;; if keysym is not a member of arglist
;;
;; keysym  - symbol. The key symbol 
;;
;; arg     - list. The list of keyword/value pairs arguments.
;;
;; message - string. Additional error message text
;; 
;; return  - any.
;;

(defun require-keyword (keysym arglist &optional (message ""))
  (let ((sublist (member keysym arglist)))
    (if sublist (car (cdr sublist))
      (warning "Required keyword missing" (symbol-name keysym) message))))


;; @doc function every-odd
;; (every-odd lst)
;; Generate new list consisting of only the odd numbered elements of argument
;; list
;; 
;; lst    - list.
;; return - list.
;;

(defun every-odd (lst)
  (if lst
      (cons (car lst)(every-odd (cdr (cdr lst))))
    nil))


;; @doc function every-even
;; (every-even lst)
;; Generate new list consisting of only the even numbered elements 
;; of argument list
;;
;; lst    - list
;; return - list
;;

(defun every-even (lst)
  (if (cdr lst)
      (cons (car (cdr lst))(every-even (cdr (cdr lst))))
    nil))


;; @doc function fifth
;; (fifth lst)
;;
;; lst    - list
;; return - any. The fifth element of lst
;;

(defun fifth (lst)
  (if lst (nth 4 lst) nil))


;; @doc function sixth
;; (sixth lst)
;;
;; lst    - list
;; return - any. The sixth element of lst
;;

(defun sixth (lst)
  (if lst (nth 5 lst) nil))


(provide 'utilities)


Main Page       Index