DSP-DEBUG is an utility to inspect the code generated by the DSP! macro. The syntax is the same of DSP! but DSP-DEBUG returns a function to call with the DSP arguments. The result of the evaluation of that function is the code generated by DSP!. Here is an example:

SCRATCH> (dsp-debug foo (freq amp pos)
           (foreach-channel
             (cout (pan2 (osc *sine-table* freq amp 0 :linear) pos))))
#<FUNCTION (LAMBDA (FREQ AMP POS &OPTIONAL ...)) {10085C184B}>
SCRATCH> (funcall * 440 .3 .5)
(LAMBDA (INCUDINE.VUG::%DSP-NODE%)
  (DECLARE (OPTIMIZE SPEED (SAFETY 0))
           (TYPE NODE INCUDINE.VUG::%DSP-NODE%))
  (INCUDINE.VUG::WITH-DSP-PREAMBLE (#:DSP538 'FOO #:CONTROL-TABLE539
                                    #:TO-FREE540 #:FREE-HOOK541)
    (INCUDINE.VUG::WITH-FOREIGN-ARRAYS ((#:SMPVEC544 #:SMPVECW543 'SAMPLE 9)
                                        (#:F32VEC546 #:F32VECW545 :FLOAT 0)
                                        (#:F64VEC548 #:F64VECW547 :DOUBLE 0)
                                        (#:I32VEC550 #:I32VECW549 :INT32 0)
                                        (#:I64VEC552 #:I64VECW551 :INT64 0)
                                        (#:PTRVEC554 #:PTRVECW553 :POINTER 1))
      (INCUDINE.VUG::WITH-SAMPLE-VARIABLES ((#:FREQ518 #:AMP519 #:POS520
                                             #:FRAC85529 #:LODIV87530 #:IN533
                                             #:ALPHA535 #:LEFT536 #:RIGHT537)
                                            #:SMPVEC544 'SAMPLE)
        (INCUDINE.VUG::WITH-FOREIGN-VARIABLES ((NIL #:F32VEC546 :FLOAT)
                                               (NIL #:F64VEC548 :DOUBLE)
                                               (NIL #:I32VEC550 :INT32)
                                               (NIL #:I64VEC552 :INT64)
                                               ((#:DATA80528) #:PTRVEC554
                                                :POINTER))
          (INCUDINE.VUG::WITH-INIT-FRAMES
            (SETF #:FREQ518 440.0d0)
            (SETF #:AMP519 0.3d0)
            (SETF #:POS520 0.5d0)
            (LET* ((#:BUF521 *SINE-TABLE*)
                   (#:FREQ-INC77525 (SAMPLE->FIXNUM (* #:FREQ518 *CPS2INC*)))
                   (#:PHS78526 0)
                   (#:MINUS-LOBITS79527 (- (BUFFER-LOBITS #:BUF521))))
              (DECLARE (TYPE BUFFER #:BUF521))
              (DECLARE (TYPE FIXNUM #:FREQ-INC77525))
              (DECLARE (TYPE FIXNUM #:PHS78526))
              (DECLARE (TYPE (INTEGER -24 0) #:MINUS-LOBITS79527))
              (SETF #:DATA80528 (BUFFER-DATA #:BUF521))
              (SETF #:LODIV87530 (BUFFER-LODIV #:BUF521))
              (LET* ((#:LOMASK88531 (BUFFER-LOMASK #:BUF521))
                     (#:MASK86532 (BUFFER-MASK #:BUF521)))
                (DECLARE (TYPE NON-NEGATIVE-FIXNUM #:LOMASK88531))
                (DECLARE (TYPE NON-NEGATIVE-FIXNUM #:MASK86532))
                (SETF #:ALPHA535 (* +HALF-PI+ #:POS520))
                (SETF #:LEFT536 (COS #:ALPHA535))
                (SETF #:RIGHT537 (SIN #:ALPHA535))
                (LABELS ()
                  (PROGN
                   (SETF (GETHASH "FREQ" #:CONTROL-TABLE539)
                           (CONS
                            (LAMBDA (#:VALUE555)
                              (DECLARE
                               (SB-EXT:MUFFLE-CONDITIONS SB-EXT:COMPILER-NOTE))
                              (SETF #:FREQ518
                                      (INCUDINE.UTIL::FORCE-SAMPLE-FORMAT
                                       #:VALUE555))
                              (SETF #:FREQ-INC77525
                                      (SAMPLE->FIXNUM (* #:FREQ518 *CPS2INC*)))
                              (VALUES))
                            (LAMBDA ()
                              (DECLARE
                               (SB-EXT:MUFFLE-CONDITIONS SB-EXT:COMPILER-NOTE))
                              #:FREQ518)))
                   (SETF (GETHASH "AMP" #:CONTROL-TABLE539)
                           (CONS
                            (LAMBDA (#:VALUE556)
                              (DECLARE
                               (SB-EXT:MUFFLE-CONDITIONS SB-EXT:COMPILER-NOTE))
                              (SETF #:AMP519
                                      (INCUDINE.UTIL::FORCE-SAMPLE-FORMAT
                                       #:VALUE556))
                              (VALUES))
                            (LAMBDA ()
                              (DECLARE
                               (SB-EXT:MUFFLE-CONDITIONS SB-EXT:COMPILER-NOTE))
                              #:AMP519)))
                   (SETF (GETHASH "POS" #:CONTROL-TABLE539)
                           (CONS
                            (LAMBDA (#:VALUE557)
                              (DECLARE
                               (SB-EXT:MUFFLE-CONDITIONS SB-EXT:COMPILER-NOTE))
                              (SETF #:POS520
                                      (INCUDINE.UTIL::FORCE-SAMPLE-FORMAT
                                       #:VALUE557))
                              (SETF #:ALPHA535 (* +HALF-PI+ #:POS520))
                              (SETF #:LEFT536 (COS #:ALPHA535))
                              (SETF #:RIGHT537 (SIN #:ALPHA535))
                              (VALUES))
                            (LAMBDA ()
                              (DECLARE
                               (SB-EXT:MUFFLE-CONDITIONS SB-EXT:COMPILER-NOTE))
                              #:POS520)))
                   (SETF (GETHASH (LIST :POINTER "FREQ") #:CONTROL-TABLE539)
                           (REDUCE-WARNINGS
                             (CONS (GET-POINTER #:FREQ518)
                                   (LAMBDA ()
                                     (DECLARE
                                      (SB-EXT:MUFFLE-CONDITIONS
                                       SB-EXT:COMPILER-NOTE))
                                     (SETF #:FREQ-INC77525
                                             (SAMPLE->FIXNUM
                                              (* #:FREQ518 *CPS2INC*)))))))
                   (SETF (GETHASH (LIST :POINTER "AMP") #:CONTROL-TABLE539)
                           (REDUCE-WARNINGS
                             (CONS (GET-POINTER #:AMP519) (LAMBDA ()))))
                   (SETF (GETHASH (LIST :POINTER "POS") #:CONTROL-TABLE539)
                           (REDUCE-WARNINGS
                             (CONS (GET-POINTER #:POS520)
                                   (LAMBDA ()
                                     (DECLARE
                                      (SB-EXT:MUFFLE-CONDITIONS
                                       SB-EXT:COMPILER-NOTE))
                                     (SETF #:ALPHA535 (* +HALF-PI+ #:POS520))
                                     (SETF #:LEFT536 (COS #:ALPHA535))
                                     (SETF #:RIGHT537 (SIN #:ALPHA535))))))
                   (SETF (GETHASH "%CONTROL-LIST%" #:CONTROL-TABLE539)
                           (CONS NIL
                                 (LAMBDA ()
                                   (DECLARE
                                    (SB-EXT:MUFFLE-CONDITIONS
                                     SB-EXT:COMPILER-NOTE))
                                   (LIST #:FREQ518 #:AMP519 #:POS520))))
                   (SETF (GETHASH "%CONTROL-NAMES%" #:CONTROL-TABLE539)
                           (CONS NIL (LAMBDA () '(FREQ AMP POS)))))
                  NIL
                  (PROGN
                   (SETF (INCUDINE.VUG::DSP-NAME #:DSP538) 'FOO)
                   (SETF (INCUDINE::NODE-CONTROLS INCUDINE.VUG::%DSP-NODE%)
                           #:CONTROL-TABLE539)
                   (INCUDINE.VUG::UPDATE-FREE-HOOK INCUDINE.VUG::%DSP-NODE%
                                                   #:FREE-HOOK541)
                   (PROGN
                    (SETF #:PHS78526
                            (LOGAND
                             (THE FIXNUM
                                  (+ #:PHS78526
                                     (SAMPLE->FIXNUM (* 0.0d0 +RAD2INC+))))
                             +PHASE-MASK+)))
                   (SETF #:TO-FREE540 INCUDINE::*TO-FREE*)
                   (INCUDINE.VUG::SET-DSP-OBJECT #:DSP538 :INIT-FUNCTION
                                                 (LAMBDA
                                                     (#:NODE542 FREQ AMP POS)
                                                   (DECLARE
                                                    (SB-EXT:MUFFLE-CONDITIONS
                                                     SB-EXT:COMPILER-NOTE))
                                                   (INCUDINE.VUG::RESET-FOREIGN-ARRAYS
                                                    #:SMPVEC544 9 8 #:F32VEC546
                                                    0 4 #:F64VEC548 0 8
                                                    #:I32VEC550 0 4 #:I64VEC552
                                                    0 8 #:PTRVEC554 1 8)
                                                   (SETF (INCUDINE::NODE-CONTROLS
                                                          #:NODE542)
                                                           (INCUDINE.VUG::DSP-CONTROLS
                                                            #:DSP538))
                                                   (SETF INCUDINE.VUG::%DSP-NODE%
                                                           #:NODE542)
                                                   (SETF INCUDINE.VUG::*DSP-NODE*
                                                           #:NODE542)
                                                   (INCUDINE.VUG::WITH-INIT-FRAMES
                                                     (INCUDINE.VUG::FREE-INCUDINE-OBJECTS
                                                      #:TO-FREE540)
                                                     (LET ((INCUDINE::*TO-FREE*
                                                            NIL))
                                                       (PROGN
                                                        (SETF #:FREQ518
                                                                (COERCE FREQ
                                                                        'SAMPLE))
                                                        (SETF #:AMP519
                                                                (COERCE AMP
                                                                        'SAMPLE))
                                                        (SETF #:POS520
                                                                (COERCE POS
                                                                        'SAMPLE))
                                                        (SETF #:BUF521
                                                                *SINE-TABLE*)
                                                        (SETF #:FREQ-INC77525
                                                                (SAMPLE->FIXNUM
                                                                 (* #:FREQ518
                                                                    *CPS2INC*)))
                                                        (SETF #:PHS78526 0)
                                                        (SETF #:MINUS-LOBITS79527
                                                                (-
                                                                 (BUFFER-LOBITS
                                                                  #:BUF521)))
                                                        (SETF #:DATA80528
                                                                (BUFFER-DATA
                                                                 #:BUF521))
                                                        (SETF #:LODIV87530
                                                                (BUFFER-LODIV
                                                                 #:BUF521))
                                                        (SETF #:LOMASK88531
                                                                (BUFFER-LOMASK
                                                                 #:BUF521))
                                                        (SETF #:MASK86532
                                                                (BUFFER-MASK
                                                                 #:BUF521))
                                                        (SETF #:ALPHA535
                                                                (* +HALF-PI+
                                                                   #:POS520))
                                                        (SETF #:LEFT536
                                                                (COS
                                                                 #:ALPHA535))
                                                        (SETF #:RIGHT537
                                                                (SIN
                                                                 #:ALPHA535)))
                                                       (INCUDINE.VUG::UPDATE-FREE-HOOK
                                                        #:NODE542
                                                        #:FREE-HOOK541)
                                                       (PROGN
                                                        (SETF #:PHS78526
                                                                (LOGAND
                                                                 (THE FIXNUM
                                                                      (+
                                                                       #:PHS78526
                                                                       (SAMPLE->FIXNUM
                                                                        (*
                                                                         0.0d0
                                                                         +RAD2INC+))))
                                                                 +PHASE-MASK+)))
                                                       (SETF #:TO-FREE540
                                                               INCUDINE::*TO-FREE*)))
                                                   #:NODE542)
                                                 :FREE-FUNCTION
                                                 (LAMBDA ()
                                                   (FREE #:SMPVECW543)
                                                   (FREE #:PTRVECW553))
                                                 :PERF-FUNCTION
                                                 (LAMBDA ()
                                                   (INCUDINE.VUG::WITH-INIT-FRAMES
                                                     (BLOCK NIL
                                                       (LET ((#:I69 0))
                                                         (DECLARE
                                                          (TYPE CHANNEL-NUMBER
                                                           #:I69))
                                                         (TAGBODY
                                                           (GO #:G71)
                                                          #:G70
                                                           (TAGBODY
                                                             (LET ((CURRENT-CHANNEL
                                                                    #:I69))
                                                               (DECLARE
                                                                (TYPE
                                                                 CHANNEL-NUMBER
                                                                 CURRENT-CHANNEL)
                                                                (IGNORABLE
                                                                 CURRENT-CHANNEL))
                                                               (PROGN
                                                                (INCF
                                                                 (AUDIO-OUT
                                                                  CURRENT-CHANNEL)
                                                                 (SAMPLE
                                                                  (IF (=
                                                                       CURRENT-CHANNEL
                                                                       0)
                                                                      (*
                                                                       #:LEFT536
                                                                       (SETF #:IN533
                                                                               (PROGN
                                                                                NIL
                                                                                (LET ((#:INDEX81
                                                                                       (THE
                                                                                        FIXNUM
                                                                                        (ASH
                                                                                         #:PHS78526
                                                                                         #:MINUS-LOBITS79527))))
                                                                                  (LET ((#:G83
                                                                                         (*
                                                                                          #:AMP519
                                                                                          (PROGN
                                                                                           (SETF #:FRAC85529
                                                                                                   (*
                                                                                                    #:LODIV87530
                                                                                                    (LOGAND
                                                                                                     #:PHS78526
                                                                                                     #:LOMASK88531)))
                                                                                           (LINEAR-INTERP
                                                                                            #:FRAC85529
                                                                                            (SMP-REF
                                                                                             #:DATA80528
                                                                                             #:INDEX81)
                                                                                            (SMP-REF
                                                                                             #:DATA80528
                                                                                             (LOGAND
                                                                                              (THE
                                                                                               FIXNUM
                                                                                               (1+
                                                                                                #:INDEX81))
                                                                                              #:MASK86532)))))))
                                                                                    (SETF #:PHS78526
                                                                                            (LOGAND
                                                                                             (THE
                                                                                              FIXNUM
                                                                                              (+
                                                                                               #:PHS78526
                                                                                               #:FREQ-INC77525))
                                                                                             +PHASE-MASK+))
                                                                                    #:G83)))))
                                                                      (IF (=
                                                                           CURRENT-CHANNEL
                                                                           1)
                                                                          (*
                                                                           #:RIGHT537
                                                                           #:IN533)
                                                                          (THE
                                                                           T
                                                                           +SAMPLE-ZERO+)))))
                                                                (VALUES))))
                                                           (PSETQ #:I69
                                                                    (1+ #:I69))
                                                          #:G71
                                                           (IF (>= #:I69
                                                                   *NUMBER-OF-OUTPUT-BUS-CHANNELS*)
                                                               NIL
                                                               (GO #:G70))
                                                           (RETURN-FROM NIL
                                                             NIL))))
                                                     (VALUES))))
                   (INCUDINE.UTIL::FINALIZE
                    (INCUDINE.VUG::DSP-INIT-FUNCTION #:DSP538)
                    (LAMBDA ()
                      (FUNCALL (INCUDINE.VUG::DSP-FREE-FUNCTION #:DSP538))
                      (INCUDINE.VUG::%%FREE-DSP-INSTANCE #:DSP538)))
                   (VALUES (INCUDINE.VUG::DSP-INIT-FUNCTION #:DSP538)
                           (INCUDINE.VUG::DSP-PERF-FUNCTION #:DSP538))))))))))))

The generated code is divided in the following parts:

The FREE-DSP-INSTANCES function frees the cached DSP instances.

SCRATCH> (free-dsp-instances)
SCRATCH> (get-foreign-sample-free-size)
67102464
SCRATCH> (get-rt-memory-free-size)
67102464

GET-FOREIGN-SAMPLE-FREE-SIZE returns the number of bytes that can be allocated from the foreign memory pool used to allocate arrays of samples in DSP and UGEN instances from the real-time thread. We can set the related memory pool size by changing the value of the configuration variable *FOREIGN-SAMPLE-POOL-SIZE* in ${HOME}/.incudinerc (the default is 64MB).

GET-RT-MEMORY-FREE-SIZE returns the free available memory allocable in realtime, without considering the allocations of SAMPLE type counted by GET-FOREIGN-SAMPLE-FREE-SIZE. We can set the size of the related memory pool by changing the value of *FOREIGN-RT-MEMORY-POOL-SIZE* in ${HOME}/.incudinerc (the default is 64MB).

The function DESTROY-DSP removes a DSP definition and all the associated memory.

The function ALL-DSP-NAMES returns all the defined DSPs. We can use the combination of DESTROY-DSP and ALL-DSP-NAMES to remove all the defined DSP:

SCRATCH> (mapc #'destroy-dsp (all-dsp-names))
SCRATCH> (all-dsp-names)
NIL

Incudine has some facilities for diagnostics. There are four levels for the logger:

Every level in the list enables the previous levels. It means that if LOGGER-LEVEL is :DEBUG, all the levels are enabled. If LOGGER-LEVEL is :ERROR, only the error messages are enabled. The default is :WARN.

*LOGGER-STREAM* and *LOGGER-FORCE-OUTPUT-P* default to *STANDARD-OUTPUT* and T, respectively.

Some examples:

SCRATCH> (logger-level)
:WARN
SCRATCH> (msg error "wrong direction")
ERROR: wrong direction
NIL
SCRATCH> (msg warn "the DSP can explode")
WARN: the DSP can explode
NIL
SCRATCH> (msg info "new group ~A" (1+ (random 100)))
NIL
SCRATCH> (setf (logger-level) :info)
:INFO
SCRATCH> (msg info "new group ~A" (1+ (random 100)))
new group 42
NIL
SCRATCH> (msg debug "the value of FREQ is ~,2F" (random 1000.0))
NIL
SCRATCH> (setf (logger-level) :debug)
:DEBUG
SCRATCH> (msg debug "the value of FREQ is ~,2F" (random 1000.0))
DEBUG: the value of FREQ is 826.75
NIL
SCRATCH> (msg info "free all nodes")
free all nodes
NIL
SCRATCH> (setf (logger-level) :error)
:ERROR
SCRATCH> (msg warn "a wolf!")
NIL
SCRATCH> (setf (logger-level) :warn)
:WARN
SCRATCH> (msg warn "a wolf!")
WARN: a wolf!
NIL
SCRATCH> (msg error "unknown device")
ERROR: unknown device
NIL

The LOGGER-TIME function returns the time unit used for the log messages. Should be one of :SEC, :SAMP or NIL (default). LOGGER-TIME is setfable.

SCRATCH> (logger-time)
NIL
SCRATCH> (setf (logger-time) :sec)
:SEC
SCRATCH> (msg warn "too late")
13878.763 WARN: too late
NIL
SCRATCH> (setf (logger-time) :samp)
:SAMP
SCRATCH> (msg warn "too late")
667113472.0 WARN: too late
NIL
SCRATCH> (setf (logger-time-function)
               (lambda ()
                 (let ((seconds-p (eq (logger-time) :sec)))
                   (format *logger-stream* "[~:[~,1F~;~,3F~]] " seconds-p
                           (* (now) (if seconds-p *sample-duration* 1))))))
SCRATCH> (msg warn "LOGGER-TIME-FUNCTION redefined")
[675466240.0] WARN: LOGGER-TIME-FUNCTION redefined
NIL
SCRATCH> (setf (logger-time-function) nil)
#<FUNCTION INCUDINE.UTIL::DEFAULT-LOGGER-TIME-FUNCTION>
SCRATCH> (setf (logger-time) nil)
NIL

We have to use NRT-MSG instead of MSG to write messages from rt-thread, the thread of the audio cycle. For example:

SCRATCH> (rt-eval () (msg warn "Don't use MSG from rt-thread!")) ; wrong
WARN: Don't use MSG from rt-thread!
NIL
SCRATCH> (setf (logger-level) :info)
:INFO
SCRATCH> (rt-eval () (nrt-msg info "NRT-MSG is ok from rt-thread"))
NRT-MSG is ok from rt-thread
NIL
SCRATCH> (setf (logger-level) :warn)
:WARN
SCRATCH> (msg warn "~A" (map 'string #'code-char '(84 72 69 32 69 78 68)))
WARN: THE END

Sourceforge project page