;;; auto-test sequence for Snd as driven from CLM
;;;
;;; to run snd under dbx while driving it from clm, 
;;;   start clm, :pa clm, (snd-open-fifos)
;;;   dbx -r snd
;;;   (receive-snd), (setf snd-is-connected t), :pa USER, :ld snd-test

(in-package :clm)

(defun decode-state (n) (if (= n 0) "MD_CS" (if (= n 1) "MD_TITLE" "MD_M")))

(setf heavy-duty 1)

(defvar hdr-dir-accessible t)		;does ~/hdr have all the CLM test sound files
(setf nap-time 4)
(setf i 0)

(run-in-shell "cp" "oboe.snd obtest.snd") ; used in save/save-as/save-mark tests
(when (probe-file "/tmp/snd_snd_fifo") (delete-file "/tmp/snd_snd_fifo"))

(let ((clm-snd-lisp (concatenate 'string "clm-snd." *clm-lisp-name*))
      (clm-snd-fasl (concatenate 'string "clm-snd." *clm-fasl-name*)))
  (when (or (not (probe-file clm-snd-fasl)) 
	    (> (file-write-date clm-snd-lisp) (file-write-date clm-snd-fasl)))
    (compile-file clm-snd-lisp))
  (load clm-snd-fasl))

(start-snd)
(sleep 2)
(print (format nil "Snd version: ~A" (snd-version))) (force-output)

(defvar ob-snd "ob.snd")
(if (not (probe-file "ob.snd")) (setf ob-snd "oboe.snd"))
(defvar now-snd "now.snd")
(if (not (probe-file "now.snd")) (setf now-snd "oboe.snd"))
(defvar four-snd "4.snd")
(if (not (probe-file "4.snd"))
    (with-sound (:channels 4 :output "4.snd" :play nil :wait t) (user::fm-violin 0 1 440 .1)))
(defvar two-snd "2.snd")
(if (not (probe-file "2.snd"))
    (with-sound (:channels 2 :output "2.snd" :play nil :wait t) (user::fm-violin 0 1 440 .1)))
(defvar four-aiff "4.aiff")
(if (not (probe-file "4.aiff")) (setf four-aiff four-snd))
(defvar two-aiff "2.aiff")
(if (not (probe-file "2.aiff")) (setf two-aiff two-snd))
(if (not (probe-file "z.snd")) (with-sound (:channels 1 :output "z.snd" :play nil :wait t) ))

(loop for test-ctr from 0 below heavy-duty do
  ;; try basic stuff

(when (> heavy-duty 1) (print (format nil "---------------- ~D ----------------~%" test-ctr)) (force-output))
(snd-open ob-snd)
(sleep 2)
(snd-play ob-snd)
(snd-dots)
(snd-hide-peaks)
(setf (snd-cursor) 1200)
(setf i (snd-cursor))
(if (/= i 1200) (print (format nil "cursor at ~D?" i)))
(snd-show-fft)
(sleep nap-time)
(snd-view now-snd)
(sleep 1)
(snd-close ob-snd)
(snd-open "z.snd")
(sleep 1)
(snd-fft-linear)
(sleep 1)
(snd-hide-wave)
(snd-close "z.snd")
(snd-show-y-zero)
(send-snd "(setf window-width 600)")
(send-snd "(setf window-height 400)")
(snd-lines)
(snd-show-peaks)
(snd-fft-db)
(snd-show-fft)
(snd-show-marks)
(setf (snd-cursor) 12000)
(setf (snd-mark "hi12") 12000)
(sleep nap-time)
(setf (snd-cursor) 6000)
(setf (snd-mark "hi6") 6000)
(sleep 1)
(setf (snd-cursor) 18000)
(snd-hide-y-zero)
(snd-fft-linear)
(snd-subsampling-off)
(snd-goto-mark "hi12")
(setf i (snd-cursor))
(if (/= i 12000) (print (format nil "cursor at ~D?" i)))
(snd-hide-fft)
(snd-x-axis 0.0 1.0)
(sleep nap-time)
(snd-x-axis 0.1 0.15)
(sleep nap-time)
(snd-hide-wave)
(snd-fft-style 1)
(snd-show-fft)
(sleep nap-time)
(snd-eval "sono_max = .5")
(snd-show-controls)
(snd-show-wave)
(snd-y-axis 3.0)
(sleep 1)
(snd-x-axis 0.0 2.0)
(snd-subsampling-on)
(snd-hide-marks)
(snd-fft-style 0)
(sleep 1)
(snd-show-peaks)
(snd-fft-log-freq)
(snd-fft-linear)
(snd-goto-mark "hi6")
(sleep 1)
(snd-hide-controls)
(snd-x-axis 0.0 0.1)
(snd-fft-style 2)
(snd-fft-linear-freq)
(sleep 1)
(snd-open ob-snd)
(snd-close now-snd)
(snd-delete 0 1200)
(sleep nap-time)
(snd-undo 1)
(sleep 1)
(snd-redo 1)
(snd-undo 1)
(snd-amp-env 0 22050 1.0 '(0 0 1 1 2 0))
(sleep 1)
(snd-undo 1)
(snd-load-function "sndlib.so" "autocorrelation")
(snd-command (char-code #\f) 4)
(snd-axes 0.0 0.2 -1.0 1.0)
(snd-sync)
(snd-open now-snd)
(snd-sync)
(snd-normalize)
(sleep nap-time)
(snd-command (char-code #\e) 4)
(snd-command (char-code #\f) 4)
;; see if snd -> clm channel is ok
(let ((ww 0) (wh 0) (fs 0) (ls 0) (rl 0.0))
  (send-snd "(window-width)")
  (setf ww (eval-snd))
  (send-snd "(window-height)")
  (setf wh (eval-snd))
  (send-snd "(fft-size)")
  (setf fs (eval-snd))
  (send-snd "(line-size)")
  (setf ls (eval-snd))
  (send-snd "(revlen)")
  (setf rl (eval-snd))
  (print (format nil "window-height ~D, window-width ~D, fft-size ~D, line-size ~D, revlen ~F " ww wh fs ls rl)))
(let ((fw 0) (fbe 0.0) (eb 0) (cb 0) (rb 0) (fb 0))
  (send-snd "(fft-window)")
  (setf fw (eval-snd))
  (send-snd "(fft-beta)")
  (setf fbe (eval-snd))
  (send-snd "(expand-button)")
  (setf eb (eval-snd))
  (send-snd "(contrast-button)")
  (setf cb (eval-snd))
  (send-snd "(reverb-button)")
  (setf rb (eval-snd))
  (send-snd "(filter-button)")
  (setf fb (eval-snd))
  (print (format nil "fft-window ~D, fft-beta ~F, exp: ~D, con: ~D, rev: ~D, flt: ~D" fw fbe eb cb rb fb)))
(let ((am 0.0) (sp 0.0) (ex 0.0) (co 0.0) (re 0.0) (fo 0))
  (send-snd "(amp)")
  (setf am (eval-snd))
  (send-snd "(speed)")
  (setf sp (eval-snd))
  (send-snd "(expand)")
  (setf ex (eval-snd))
  (send-snd "(revscl)")
  (setf re (eval-snd))
  (send-snd "(contrast)")
  (setf co (eval-snd))
  (send-snd "(filter-order)")
  (setf fo (eval-snd))
  (print (format nil "amp: ~F, speed: ~F, contrast: ~F, expand: ~F, revscl: ~F, filter-order: ~D" am sp co ex re fo)))
(snd-unsync)
;; try various keyboard commands  
(send-snd "(just-sounds)")
(snd-goto-sound ob-snd)
(snd-command (char-code #\>) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\<) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\>) 0)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\<) 0)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\a) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\e) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\b) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\p) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\n) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\l) 4)
(snd-command (char-code #\x) 4) (snd-command (char-code #\b) 0)
(send-snd "(function autocorrelation 1)")
(setf (snd-cursor) 1200)
(snd-setf-region 1000 2000)
(snd-cut)
(setf (snd-cursor) 0)
(snd-paste 0)
(sleep 3)
(snd-revert ob-snd)
(snd-find "y>.1")
(sleep 1)
(snd-command (char-code #\m) 4)
(snd-command (char-code #\v) 4)
(snd-command (char-code #\d) 4)
(snd-command (char-code #\z) 4)
(snd-command (char-code #\o) 4)
(snd-command (char-code #\x) 4) (snd-command (char-code #\u) 0)
(snd-undo 2)
(sleep 1)
(snd-command (char-code #\<) 4)  (snd-command (char-code #\i) 4)  
(send-snd "(function autocorrelation -1)") ; turn it off
(snd-axes 0.0 0.1 -0.5 0.5)
(sleep 1)
(let ((data (make-array 32 :element-type 'integer :initial-element 8192))
      (indata nil))
  (snd-insert 600 32 data)
  (sleep 1)
  (loop for i from 0 to 31 do (setf (aref data i) (* (- 32 i) 256)))
  (snd-change 632 32 data)
  (sleep 1)
  (setf (snd-cursor) 0)
  (sleep nap-time)
  (snd-undo 1)
  (snd-undo 1)
  (snd-redo 2)
  (snd-undo 2)
  (sleep 1)
  (snd-setf-region 1000 1010)
  (sleep 1)
  (setf indata (snd-region 0))		; first int is chans, then 10 words of data presumably
  (print indata))
(snd-command (char-code #\w) 4)		; delete region
(sleep 1)
(snd-command (char-code #\y) 4)		; paste region
(snd-command (char-code #\q) 4)		; play
(sleep 1)
(snd-command (char-code #\t) 4)		; stop
(setf (snd-cursor) 8000)
(snd-command (char-code #\x) 4) (snd-command (char-code #\f) 0)
(snd-command (char-code #\x) 4) (snd-command (char-code #\i) 0)
;(snd-command (char-code #\x) 4) (snd-command (char-code #\q) 0)
(snd-command (char-code #\x) 4) (snd-command (char-code #\l) 0)
(snd-command (char-code #\x) 4) (snd-command (char-code #\u) 0)
(snd-command (char-code #\x) 4) (snd-command (char-code #\r) 0)
(snd-command (char-code #\x) 4) (snd-command (char-code #\v) 0)
(snd-command (char-code #\x) 4) (snd-command (char-code #\o) 4)
(sleep 1)
(snd-command (char-code #\x) 4) (snd-command (char-code #\u) 4)
(snd-revert ob-snd)
;; now pound on file open/close for awhile
(snd-command (char-code #\x) 4) (snd-command (char-code #\k) 0)
(snd-close now-snd)
(sleep 2)
;; should be just menu-bar here
;; most commands work, pound on file open/close (widgets get a work out and sound list gets reallocated)
(when hdr-dir-accessible
  (snd-open "~/hdr/o2.bicsf") (sleep nap-time)
  (snd-open "~/hdr/riff-8-u.snd") (sleep nap-time)
  (snd-close "~/hdr/riff-8-u.snd") 
  (snd-open "~/hdr/wood.riff") (sleep nap-time)
  (snd-close "~/hdr/o2.bicsf") 
  (snd-open "~/hdr/wood.maud") (sleep nap-time)
  (snd-open "~/hdr/wood.sf") (sleep nap-time)
  (snd-close "~/hdr/wood.maud") 
  (snd-close "~/hdr/wood.riff") 
  (snd-open "~/hdr/wood12.aiff") (sleep nap-time)
  (snd-open "~/hdr/wood24.aiff") (sleep nap-time)
  (snd-close "~/hdr/wood.sf") 
  (snd-open "~/hdr/next24.snd") (sleep nap-time)
  (snd-open "~/hdr/esps-16.snd") (sleep nap-time)
  (snd-close "~/hdr/next24.snd") 
  (snd-close "~/hdr/esps-16.snd")
  (snd-close "~/hdr/wood12.aiff")
  (snd-close "~/hdr/wood24.aiff")
  (snd-open "~/hdr/sd1-16.snd") (sleep nap-time)
  (snd-open "~/hdr/inrs-16.snd") (sleep nap-time)
  (snd-open "~/hdr/sun-16-afsp.snd") (sleep nap-time)
  (snd-open "~/hdr/next-16.snd") (sleep nap-time)
  (snd-open "~/hdr/sun-mulaw.snd") (sleep nap-time)
  (snd-open "~/hdr/next-mulaw.snd") (sleep nap-time)
  (snd-normalize) (sleep nap-time)
  (snd-open "~/hdr/next-8.snd") (sleep nap-time)
  (snd-close "~/hdr/inrs-16.snd") 
  (snd-close "~/hdr/sun-16-afsp.snd") 
  (snd-close "~/hdr/next-16.snd")
  (snd-open "~/hdr/nist-16.snd") (sleep nap-time)
  (snd-close "~/hdr/sd1-16.snd") 
  (snd-close "~/hdr/sun-mulaw.snd") 
  (snd-open "~/hdr/voc-8-u.snd") (sleep nap-time)
  (snd-open "~/hdr/riff-16.snd") (sleep nap-time)
  (snd-open "~/hdr/aiff-8.snd") (sleep nap-time)
  (snd-open "~/hdr/aiff-16.snd") (sleep nap-time)
  (snd-normalize) (sleep nap-time)
  (snd-close "~/hdr/nist-16.snd") 
  (snd-close "~/hdr/voc-8-u.snd") 
  (snd-close "~/hdr/riff-16.snd") 
  (snd-close "~/hdr/aiff-8.snd") 
  (snd-open "~/hdr/woodblock.aiff") (sleep nap-time)
  (snd-close "~/hdr/next-mulaw.snd") 
  (snd-close "~/hdr/next-8.snd") 
  (snd-close "~/hdr/aiff-16.snd")
  (snd-open "~/hdr/ulaw.aifc") (sleep nap-time)
  (snd-open "~/hdr/alaw.aifc") (sleep nap-time)
  (snd-close "~/hdr/woodblock.aiff")
  (snd-close "~/hdr/ulaw.aifc")
  (snd-close "~/hdr/alaw.aifc")
  (snd-open "~/hdr/kirk.wve") (sleep nap-time)
  (snd-open "~/hdr/addf8.d") (sleep nap-time)
  (snd-close "~/hdr/kirk.wve")
  (snd-close "~/hdr/addf8.d") (sleep nap-time))

;; basic stuff is ok -- now pound on regions and the sync button (multi-channel ops)
(snd-open four-snd)
(send-snd "(setf window-width 600)")
(send-snd "(setf window-height 800)")
(snd-normalize) (sleep 1)
(snd-command (char-code #\x) 4) (snd-command (char-code #\o) 0)
(sleep 1)
(snd-command (char-code #\x) 4) (snd-command (char-code #\o) 0)

(let ((data (make-array 32 :element-type 'integer :initial-element 8192))
      (indata nil))
  (loop for k from 0 to 3 do
	(snd-insert 600 32 data)
	(sleep 1)
	(loop for i from 0 to 31 do (setf (aref data i) (* (- 32 i) 256)))
	(snd-change 632 32 data)
	(sleep 1)
	(loop for j from 0 to 6 do
	      (snd-command (char-code #\m) 4)
	      (setf (snd-cursor) (* j 1000)))
	(setf (snd-cursor) 0)
	(sleep nap-time)
	(snd-undo 1)
	(snd-undo 1)
	(snd-redo 2)
	(snd-undo 2)
	(sleep 1)
	(snd-setf-region 1000 1010)
	(snd-command (char-code #\w) 4)	; delete region
	(sleep 1)
	(snd-command (char-code #\y) 4)	; paste region
	(snd-command (char-code #\x) 4) (snd-command (char-code #\o) 0)))
(snd-open two-snd)
(snd-sync)
(let ((data (make-array 32 :element-type 'integer :initial-element 8192))
      (indata nil))
  (loop for k from 0 to 1 do
	(loop for j from 0 to 6 do
	      (snd-command (char-code #\m) 4)
	      (setf (snd-cursor) (* j 1000)))
	(snd-insert 600 32 data)
	(sleep 1)
	(loop for i from 0 to 31 do (setf (aref data i) (* (- 32 i) 256)))
	(snd-change 632 32 data)
	(sleep 1)
	(setf (snd-cursor) 0)
	(sleep nap-time)
	(snd-undo 1)
	(snd-undo 1)
	(snd-redo 2)
	(snd-undo 2)
	(sleep 1)
	(snd-setf-region 1000 1010)
	(snd-command (char-code #\w) 4)	; delete region
	(sleep 1)
	(snd-command (char-code #\y) 4)	; paste region
	(snd-command (char-code #\x) 4) (snd-command (char-code #\o) 0)))
(snd-open ob-snd)
(snd-revert four-snd)
(snd-revert two-snd)
(sleep nap-time)
(snd-close four-snd)
(snd-close two-snd)
(loop for i from 0 to 30 do
      (snd-setf-region (* i 100) (* i 110))
      (when (> (random 1.0) .5) (snd-command (char-code #\x) 4) (snd-command (char-code #\p) 0)))
(sleep nap-time)
(snd-close ob-snd)
(snd-open two-snd)
(snd-open ob-snd)
(sleep nap-time)
(snd-open four-snd)
(snd-normalize)
(sleep nap-time)
(snd-close four-snd)
(snd-close two-snd)
(snd-close ob-snd)
(sleep nap-time)
(snd-open ob-snd)
(snd-sync)
(snd-open four-snd)
(snd-sync)
(snd-open two-snd)
(snd-sync)
;; now multi-channel ops
(snd-command (char-code #\>) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\<) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\>) 0)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\<) 0)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\a) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\e) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\b) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\p) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\n) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\l) 4)
(snd-command (char-code #\x) 4) (snd-command (char-code #\b) 0)
(setf (snd-cursor) 1200)
(snd-setf-region 1000 2000)
(snd-cut)
(setf (snd-cursor) 0)
(snd-paste 0)
(sleep 3)
(snd-undo 2)
(snd-redo)
(snd-undo)
(sleep 2)
(snd-redo)
(sleep 2)
(snd-undo)
(snd-unsync)
(snd-close two-snd)
(snd-close four-snd)
(snd-close ob-snd)
(snd-open four-aiff)
(snd-sync)
(snd-open two-aiff)
(snd-sync)
;; now multi-channel ops
(snd-command (char-code #\>) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\<) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\>) 0)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\<) 0)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\a) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\e) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\b) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\p) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\n) 4)  (snd-command (char-code #\i) 4)  
(snd-command (char-code #\l) 4)
(snd-command (char-code #\x) 4) (snd-command (char-code #\b) 0)
(setf (snd-cursor) 1200)
(snd-setf-region 1000 2000)
(snd-cut)
(setf (snd-cursor) 0)
(snd-paste 0)
(sleep 3)
(snd-undo 2)
(snd-redo)
(snd-undo)
(sleep 2)
(snd-redo)
(sleep 2)
(snd-undo)
(snd-unsync)
(snd-close four-aiff)
(snd-close two-aiff)
;; now edit/mark/save/save-as tests
(snd-open "obtest.snd")
;; mark, edit, mark, edit, mark, edit, undo, save-as obtest1, check the marks
(setf (snd-mark "ob1") 500)
(snd-delete 200 100)
(setf (snd-mark "ob2") 600)
(snd-delete 800 100)
(setf (snd-mark "ob3") 25)
(snd-undo)
;; now there should be ob1 at 400, ob2 at 600, ob3 reported at 0 (since it's been deleted)
(let ((ob1 (snd-mark "ob1"))
      (ob2 (snd-mark "ob2"))
      (ob3 (snd-mark "ob3")))
  (snd-save "obtest.snd")
  (let ((ob11 (snd-mark "ob1"))
	(ob21 (snd-mark "ob2"))
	(ob31 (snd-mark "ob3")))
    (when (or (/= ob1 ob11) (/= ob2 ob21) (/= ob3 ob31))
      (print (format nil "~d ~d, ~d ~d, ~d ~d?" ob1 ob11 ob2 ob21 ob3 ob31)) 
      (force-output))))
(snd-save-marks)
(snd-save-as "obtest.snd" "obtest1.snd")
;(snd-close "obtest1.snd")
;(snd-open "obtest.snd")
;; marks should exist
(let ((ob1 (snd-mark "ob1"))
      (ob2 (snd-mark "ob2"))
      (ob3 (snd-mark "ob3")))
  (when (or (/= ob1 400) (/= ob2 600) (/= ob3 0))
    (print (format nil "~d ~d ~d?" ob1 ob2 ob3))
    (force-output)))
(snd-close "obtest.snd")
;; TODO: amplitude envelopes

)

;(sleep 3)
(snd-open "oboe.snd")
(sleep 3)
(send-snd "(mix pistol.snd 0 -1 0 -1)")
;;; mix name beg len[-1=full] temp group[-1=none]
(sleep 1)

(send-snd "(setf window-width 800)")
(send-snd "(setf window-height 600)")

(let ((beg (progn (send-snd "(mix-position 1)") (eval-snd)))
      (len (progn (send-snd "(mix-length 1)") (eval-snd)))
      (anchor (progn (send-snd "(mix-anchor 1)") (eval-snd)))
      (state (progn (send-snd "(mix-state 1)") (eval-snd)))
      (speed (progn (send-snd "(mix-speed 1)") (eval-snd)))
      (amp (progn (send-snd "(mix-amp 1 0)") (eval-snd))))
  (print (format nil "mix: ~D for ~D anchored at ~D, state: ~A, speed: ~,3F, amp[0]: ~,3F" beg len anchor (decode-state state) speed amp))
  )

(snd-x-axis 0.0 0.3)

(send-snd "(setf (mix-position 1) 1234)")
(sleep 1)
(send-snd "(setf (mix-state 1) 0)")
(sleep 1)
(send-snd "(setf (mix-speed 1) .5)")
(sleep 1)
(send-snd "(setf (mix-anchor 1) 1000)")
(send-snd "(setf (mix-amp 1 0) 2.0)")

(let ((beg (progn (send-snd "(mix-position 1)") (eval-snd)))
      (len (progn (send-snd "(mix-length 1)") (eval-snd)))
      (anchor (progn (send-snd "(mix-anchor 1)") (eval-snd)))
      (state (progn (send-snd "(mix-state 1)") (eval-snd)))
      (speed (progn (send-snd "(mix-speed 1)") (eval-snd)))
      (amp (progn (send-snd "(mix-amp 1 0)") (eval-snd))))
  (print (format nil "mix: ~D for ~D anchored at ~D, state: ~A, speed: ~,3F, amp[0]: ~,3F" beg len anchor (decode-state state) speed amp))
  )

(sleep 3)
(snd-revert "oboe.snd")
(send-snd "(mix pistol.snd 0 5000 0 -1)")
(send-snd "(setf (mix-amp 1 0) .5)")
(sleep 2)
(send-snd "(mix pistol.snd 3000 5000 0 -1)")
(send-snd "(mix pistol.snd 6000 5000 0 -1)")

(loop for i from 1 to 3 do (send-snd (format nil "(setf (mix-groups ~D) 1)" i)))

(let ((beg (progn (send-snd "(group-beg 0)") (eval-snd)))
      (end (progn (send-snd "(group-end 0)") (eval-snd)))
      (speed (progn (send-snd "(group-speed 0)") (eval-snd)))
      (tempo (progn (send-snd "(group-tempo 0)") (eval-snd)))
      (amp (progn (send-snd "(group-amp 0 0)") (eval-snd))))
  (print (format nil "group beg: ~,3F, end: ~,3F, speed: ~,3F, tempo: ~,3F, amp[0]: ~,3F" beg end speed tempo amp)))

(send-snd "(setf (group-beg 0) .1)")
(send-snd "(setf (group-speed 0) .5)")
(send-snd "(setf (group-amp 0 0) 2.0)")
(send-snd "(setf (group-tempo 0) .75)")

(let ((beg (progn (send-snd "(group-beg 0)") (eval-snd)))
      (end (progn (send-snd "(group-end 0)") (eval-snd)))
      (speed (progn (send-snd "(group-speed 0)") (eval-snd)))
      (tempo (progn (send-snd "(group-tempo 0)") (eval-snd)))
      (amp (progn (send-snd "(group-amp 0 0)") (eval-snd))))
  (print (format nil "group beg: ~,3F, end: ~,3F, speed: ~,3F, tempo: ~,3F, amp[0]: ~,3F" beg end speed tempo amp)))


#|
(snd-open "cardinal.snd")
(sleep 3)
(send-snd (format nil "(mix ramp.snd ~D 100000 0 -1)" (+ 10000 (* i 10000))))
|#
(print "finished normally")

#|  
(sleep 10)
(stop-snd)

(run-in-shell "rm" "obtest.snd")
(run-in-shell "rm" "obtest1.snd")
(run-in-shell "rm" "obtest.snd.marks")
|#
