(require :incudine-snd)

(in-package :scratch)

SCRATCH> snd:*program-name*
"snd"
         ;; Snd command line argument list.
SCRATCH> snd:*program-args*
NIL
         ;; Temporary soundfile.
SCRATCH> snd:*tmpfile*
"/tmp/incudine-snd.snd"

;; It is possible to use the Emacs' Snd-Scheme mode. It requires
;; slime-enable-evaluate-in-emacs T on the Emacs side, then
;;
;;     (setf (snd:emacs-mode-p) t)

SCRATCH> (snd:run)
#<SB-IMPL::PROCESS 1955 :RUNNING>

SCRATCH> (dsp! hello-snd (c i a o)
           (stereo (+ (sine c i 0) (sine a o 0))))

SCRATCH> (bounce-to-snd ("/tmp/oscilla.wav")
           (hello-snd 230 .2 255 .1))
(SOUND 0)

SCRATCH> (snd:enable-sharp-s7-syntax)

SCRATCH> (defun snd-play ()
           (snd:eval #s7(play)))

SCRATCH> (snd-play)

SCRATCH> (bounce-to-snd-mix ("/tmp/oscilla-2.wav")
           (hello-snd 430 .2 495 .1))
((MIX 0))

SCRATCH> (bounce-to-snd-mix ("/tmp/oscilla-3.wav" '(48000 t))
           (hello-snd 1000 .2 1220 .1))
((MIX 1) (MIX 2))

SCRATCH> (snd:eval #s7(set! (cursor) 108000))
108000

SCRATCH> (bounce-to-snd-mix ("/tmp/oscilla-4.wav" '("(cursor)" t) :duration 1)
           (hello-snd 660 .1 888 .1))
((MIX 3) (MIX 4))

SCRATCH> (snd:eval #s7(set! (cursor) 0))
0

SCRATCH> (snd-play)

SCRATCH> (defvar *mix0* (snd:mix->buffer 0))

SCRATCH> *mix0*
#<BUFFER :FRAMES 96000 :CHANNELS 1 :SR 48000.0>

SCRATCH> (defvar *snd0* (snd:sound->buffer 0))

SCRATCH> *snd0*
#<BUFFER :FRAMES 156000 :CHANNELS 2 :SR 48000.0>

SCRATCH> (dsp! bplay ((buf buffer) rate start-pos (loop-p boolean))
           (foreach-channel
             (cout (buffer-play buf rate start-pos loop-p #'free))))

SCRATCH> (set-rt-block-size 1)

SCRATCH> (rt-start)

SCRATCH> (bplay *snd0* 1 0 t)

SCRATCH> (snd:eval #s7(set! (selection-position) 73000))
73000

SCRATCH> (snd:eval #s7(set! (selection-framples) 48000))
48000

SCRATCH> (defvar *snd-sel* (snd:selection->buffer))

SCRATCH> *snd-sel*
#<BUFFER :FRAMES 48000 :CHANNELS 2 :SR 48000.0>

SCRATCH> (set-control 1 :buf *snd-sel*)

SCRATCH> (snd:eval #s7(set! (selection-position) 20000))
20000

SCRATCH> (snd:eval #s7(set! (selection-framples) 48000) :output-p nil)
NIL

SCRATCH> (defvar *snd-reg0*
           (snd:region->buffer (second (snd:eval #s7(make-region)))))

SCRATCH> *snd-reg0*
#<BUFFER :FRAMES 48000 :CHANNELS 2 :SR 48000.0>

SCRATCH> (set-control 1 :buf *snd-reg0*)

SCRATCH> (snd:eval #s7(unselect-all))
NIL

SCRATCH> (free 0)

SCRATCH> (rt-stop)

SCRATCH> (snd:eval #s7(begin (save-sound) (close-sound)))
NIL

SCRATCH> (snd:buffer->sound *snd0* "/tmp/snd0.wav")
(SOUND 0)

SCRATCH> (snd:eval #s7(scale-to .3))
0.3

SCRATCH> (snd:buffer->mix *snd-sel*)
((MIX 0))

SCRATCH> (snd:buffer->mix *mix0* '(108000 0 nil 0))
((MIX 1))

SCRATCH> (snd:buffer->mix *mix0* '("/tmp/mix0.wav" 108000 0 nil 1))
((MIX 2))

SCRATCH> (snd:eval #s7(maxamp))
0.9025847

SCRATCH> (with-open-file (f "/tmp/666.scm" :direction :output
                          :if-exists :supersede)
           (write-line "(reverse-sound)" f))

SCRATCH> (snd:load "/tmp/666.scm")
NIL

SCRATCH> (snd:mix "/tmp/oscilla-2.wav" '(76400 t))
((MIX 3) (MIX 4))

SCRATCH> (dotimes (ch 2)
           (let ((n -1))
             (snd:map-channel (lambda (x) (* x (incf n) 1/80000))
                              :dur 80000 :chn ch)))

SCRATCH> (with-cleanup
           #snd(begin (set! (selection-position) (- (framples) 48000))
                      (set! (selection-framples) 48000))
           (snd:env-selection (make-cutoff 1)))

SCRATCH> (snd-play)

         ;; exorcize-filter
SCRATCH> (buffer-save *snd0* "/tmp/snd0.wav")
SCRATCH> (snd:open-or-update-sound "/tmp/snd0.wav")
(SOUND 0)

SCRATCH> (with-cleanup
           (let ((env (make-adsr .5 .09 .8 1.2)))
             (dotimes (ch 2) (snd:env-channel env :chn ch))))

SCRATCH> (snd-play)

SCRATCH> (snd:eval #s7(length (define cudotest (channel->float-vector))))

SCRATCH> (defvar *fvec0* (snd:float-vector->buffer "cudotest"))

SCRATCH> *fvec0*
#<BUFFER :FRAMES 156000 :CHANNELS 1 :SR 48000.0>

SCRATCH> (subseq (buffer->list *fvec0*) 0 10)
(0.0d0 2.803304452250499d-6 1.0656883961029175d-5 2.3519001276374212d-5
 4.132131854014835d-5 6.396912508799108d-5 9.134190665801465d-5
 1.232938527676509d-4 1.5965481562650003d-4 2.002306897983181d-4)

SCRATCH> (snd:eval #s7(set! (transform-graph?) #t))

SCRATCH> (defvar *fvec1*
           (snd:float-vector->buffer "(transform->float-vector)"))

SCRATCH> *fvec1*
#<BUFFER :FRAMES 512 :CHANNELS 1 :SR 48000.0>

SCRATCH> (snd:float-vector "cudotest2" *fvec1*)
512

SCRATCH> (snd:eval #s7(length cudotest2))
512

SCRATCH> (snd:float-vector "cudotest3" '(1 2 3 5 8 13 21))
7

SCRATCH> (snd:eval "cudotest3")
"#r(1.0 2.0 3.0 5.0 8.0 13.0 21.0)"

SCRATCH> (snd:float-vector "cudotest4" #(1 2 3 5 8 13 21) 2 7)
5

SCRATCH> (snd:eval #s7(cudotest4 3))
13.0

SCRATCH> (snd:float-vector "cudotest5" (gen:partials '(5 4 3 2 1)) 0 1024)
1024

SCRATCH> (snd:eval #s7(set! (lisp-graph?) #t))

SCRATCH> (snd:eval #s7(graph cudotest5 "cudonics"))

SCRATCH> #s7(let ((snd (open-sound "/tmp/snd0.wav")))
              (play snd :wait #t))
"(let ((snd (open-sound \"/tmp/snd0.wav\"))) (play snd :wait #t))"

SCRATCH> #s7(quote #.(LOOP REPEAT 8 COLLECT (RANDOM 1.0)))
"(quote
  (0.5520501 0.4115485 0.35940528 0.0056368113 0.31019592
   0.4214077 0.32522345 0.2879219))"

SCRATCH> (format nil #s7(new-sound "/tmp/foo.wav" :channels 1 :size ~D)
                 (floor incudine.util:*sample-rate*))
"(new-sound \"/tmp/foo.wav\" :channels 1 :size 48000)"

#snd(...)   is equivalent to  (snd:eval #s7(...))
#0snd(...)  is equivalent to  (snd:eval #s7(...) :output-p nil)

hidden side effect:  #7s is equivalent to #s7

SCRATCH> (defstruct point x y)
SCRATCH> #s(point)
#S(POINT :X NIL :Y NIL)

SCRATCH> #snd(list #t #f ())
(T NIL NIL)

SCRATCH> #0snd(define foo 123)
NIL

SCRATCH> #snd(list foo)
(123)

SCRATCH> (snd:exit)
T

Sourceforge project page