DSP-DEBUG is an utility to debug a definition of a DSP. The syntax is the same of DSP! but DSP-DEBUG returns a function to call with the arguments of the DSP. 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 (#:DSP912 'FOO #:CONTROL-TABLE913
                                    #:FREE-HOOK914)
    (INCUDINE.VUG::WITH-FOREIGN-ARRAYS ((#:SMPVEC917 #:SMPVECW916 'SAMPLE 7)
                                        (#:F32VEC919 #:F32VECW918 :FLOAT 0)
                                        (#:F64VEC921 #:F64VECW920 :DOUBLE 0)
                                        (#:I32VEC923 #:I32VECW922 :INT32 0)
                                        (#:I64VEC925 #:I64VECW924 :INT64 0)
                                        (#:PTRVEC927 #:PTRVECW926 :POINTER 1))
      (INCUDINE.VUG::WITH-SAMPLE-VARIABLES ((#:ALPHA911 #:IN909 #:LODIV138906
                                             #:FRAC136905 #:POS897 #:AMP896
                                             #:FREQ895)
                                            #:SMPVEC917 'SAMPLE)
        (INCUDINE.VUG::WITH-FOREIGN-VARIABLES ((NIL #:F32VEC919 :FLOAT)
                                               (NIL #:F64VEC921 :DOUBLE)
                                               (NIL #:I32VEC923 :INT32)
                                               (NIL #:I64VEC925 :INT64)
                                               ((#:DATA133904) #:PTRVEC927
                                                :POINTER))
          (SETF #:FREQ895 440.0d0)
          (SETF #:AMP896 0.3d0)
          (SETF #:POS897 0.5d0)
          (LET* ((#:%BUFFER127898 *SINE-TABLE*)
                 (#:FREQ-INC130901 (SAMPLE->FIXNUM (* #:FREQ895 *CPS2INC*)))
                 (#:PHS131902 0)
                 (#:MINUS-LOBITS132903 (- (BUFFER-LOBITS #:%BUFFER127898))))
            (DECLARE (TYPE BUFFER #:%BUFFER127898))
            (DECLARE (TYPE FIXNUM #:FREQ-INC130901))
            (DECLARE (TYPE FIXNUM #:PHS131902))
            (DECLARE (TYPE (INTEGER -24 0) #:MINUS-LOBITS132903))
            (SETF #:DATA133904 (BUFFER-DATA #:%BUFFER127898))
            (SETF #:LODIV138906 (BUFFER-LODIV #:%BUFFER127898))
            (LET* ((#:LOMASK139907 (BUFFER-LOMASK #:%BUFFER127898))
                   (#:MASK137908 (BUFFER-MASK #:%BUFFER127898)))
              (DECLARE (TYPE NON-NEGATIVE-FIXNUM #:LOMASK139907))
              (DECLARE (TYPE NON-NEGATIVE-FIXNUM #:MASK137908))
              (SETF #:ALPHA911 (* +HALF-PI+ #:POS897))
              (LABELS ()
                (PROGN
                 (SETF (GETHASH "FREQ" #:CONTROL-TABLE913)
                         (CONS
                          (LAMBDA (#:VALUE928)
                            (DECLARE
                             (SB-EXT:MUFFLE-CONDITIONS SB-EXT:COMPILER-NOTE))
                            (SETF #:FREQ895 (COERCE #:VALUE928 'SAMPLE))
                            (SETF #:FREQ-INC130901
                                    (SAMPLE->FIXNUM (* #:FREQ895 *CPS2INC*)))
                            (VALUES))
                          (LAMBDA ()
                            (DECLARE
                             (SB-EXT:MUFFLE-CONDITIONS SB-EXT:COMPILER-NOTE))
                            #:FREQ895)))
                 (SETF (GETHASH "AMP" #:CONTROL-TABLE913)
                         (CONS
                          (LAMBDA (#:VALUE929)
                            (DECLARE
                             (SB-EXT:MUFFLE-CONDITIONS SB-EXT:COMPILER-NOTE))
                            (SETF #:AMP896 (COERCE #:VALUE929 'SAMPLE))
                            (VALUES))
                          (LAMBDA ()
                            (DECLARE
                             (SB-EXT:MUFFLE-CONDITIONS SB-EXT:COMPILER-NOTE))
                            #:AMP896)))
                 (SETF (GETHASH "POS" #:CONTROL-TABLE913)
                         (CONS
                          (LAMBDA (#:VALUE930)
                            (DECLARE
                             (SB-EXT:MUFFLE-CONDITIONS SB-EXT:COMPILER-NOTE))
                            (SETF #:POS897 (COERCE #:VALUE930 'SAMPLE))
                            (SETF #:ALPHA911 (* +HALF-PI+ #:POS897))
                            (VALUES))
                          (LAMBDA ()
                            (DECLARE
                             (SB-EXT:MUFFLE-CONDITIONS SB-EXT:COMPILER-NOTE))
                            #:POS897)))
                 (SETF (GETHASH (LIST :POINTER "FREQ") #:CONTROL-TABLE913)
                         (REDUCE-WARNINGS
                           (CONS (GET-POINTER #:FREQ895)
                                 (LAMBDA ()
                                   (DECLARE
                                    (SB-EXT:MUFFLE-CONDITIONS
                                     SB-EXT:COMPILER-NOTE))
                                   (SETF #:FREQ-INC130901
                                           (SAMPLE->FIXNUM
                                            (* #:FREQ895 *CPS2INC*)))))))
                 (SETF (GETHASH (LIST :POINTER "AMP") #:CONTROL-TABLE913)
                         (REDUCE-WARNINGS
                           (CONS (GET-POINTER #:AMP896) (LAMBDA ()))))
                 (SETF (GETHASH (LIST :POINTER "POS") #:CONTROL-TABLE913)
                         (REDUCE-WARNINGS
                           (CONS (GET-POINTER #:POS897)
                                 (LAMBDA ()
                                   (DECLARE
                                    (SB-EXT:MUFFLE-CONDITIONS
                                     SB-EXT:COMPILER-NOTE))
                                   (SETF #:ALPHA911 (* +HALF-PI+ #:POS897))))))
                 (SETF (GETHASH "%CONTROL-LIST%" #:CONTROL-TABLE913)
                         (CONS NIL
                               (LAMBDA ()
                                 (DECLARE
                                  (SB-EXT:MUFFLE-CONDITIONS
                                   SB-EXT:COMPILER-NOTE))
                                 (LIST #:FREQ895 #:AMP896 #:POS897))))
                 (SETF (GETHASH "%CONTROL-NAMES%" #:CONTROL-TABLE913)
                         (CONS NIL (LAMBDA () '(FREQ AMP POS)))))
                NIL
                (PROGN
                 (SETF (INCUDINE.VUG::DSP-NAME #:DSP912) 'FOO)
                 (SETF (INCUDINE::NODE-CONTROLS INCUDINE.VUG::%DSP-NODE%)
                         #:CONTROL-TABLE913)
                 (INCUDINE.VUG::UPDATE-FREE-HOOK INCUDINE.VUG::%DSP-NODE%
                                                 #:FREE-HOOK914)
                 (INCUDINE.VUG::SET-DSP-OBJECT #:DSP912 :INIT-FUNCTION
                                               (LAMBDA (#:NODE915 FREQ AMP POS)
                                                 (DECLARE
                                                  (SB-EXT:MUFFLE-CONDITIONS
                                                   SB-EXT:COMPILER-NOTE))
                                                 (INCUDINE.VUG::RESET-FOREIGN-ARRAYS
                                                  #:SMPVEC917 7 8 #:F32VEC919 0
                                                  4 #:F64VEC921 0 8 #:I32VEC923
                                                  0 4 #:I64VEC925 0 8
                                                  #:PTRVEC927 1 8)
                                                 (SETF (INCUDINE::NODE-CONTROLS
                                                        #:NODE915)
                                                         (INCUDINE.VUG::DSP-CONTROLS
                                                          #:DSP912))
                                                 (SETF INCUDINE.VUG::%DSP-NODE%
                                                         #:NODE915)
                                                 (PROGN
                                                  (SETF #:FREQ895
                                                          (COERCE FREQ
                                                                  'SAMPLE))
                                                  (SETF #:AMP896
                                                          (COERCE AMP 'SAMPLE))
                                                  (SETF #:POS897
                                                          (COERCE POS 'SAMPLE))
                                                  (SETF #:%BUFFER127898
                                                          *SINE-TABLE*)
                                                  (SETF #:FREQ-INC130901
                                                          (SAMPLE->FIXNUM
                                                           (* #:FREQ895
                                                              *CPS2INC*)))
                                                  (SETF #:PHS131902 0)
                                                  (SETF #:MINUS-LOBITS132903
                                                          (-
                                                           (BUFFER-LOBITS
                                                            #:%BUFFER127898)))
                                                  (SETF #:DATA133904
                                                          (BUFFER-DATA
                                                           #:%BUFFER127898))
                                                  (SETF #:LODIV138906
                                                          (BUFFER-LODIV
                                                           #:%BUFFER127898))
                                                  (SETF #:LOMASK139907
                                                          (BUFFER-LOMASK
                                                           #:%BUFFER127898))
                                                  (SETF #:MASK137908
                                                          (BUFFER-MASK
                                                           #:%BUFFER127898))
                                                  (SETF #:ALPHA911
                                                          (* +HALF-PI+
                                                             #:POS897)))
                                                 (INCUDINE.VUG::UPDATE-FREE-HOOK
                                                  #:NODE915 #:FREE-HOOK914)
                                                 #:NODE915)
                                               :FREE-FUNCTION
                                               (LAMBDA ()
                                                 (FREE #:SMPVECW916)
                                                 (FREE #:PTRVECW926))
                                               :PERF-FUNCTION
                                               (LAMBDA ()
                                                 (LET ((CURRENT-CHANNEL 0))
                                                   (DECLARE
                                                    (TYPE CHANNEL-NUMBER
                                                     CURRENT-CHANNEL)
                                                    (IGNORABLE
                                                     CURRENT-CHANNEL))
                                                   (BLOCK NIL
                                                     (LET ((#:I124 0))
                                                       (DECLARE
                                                        (TYPE CHANNEL-NUMBER
                                                         #:I124))
                                                       (TAGBODY
                                                         (GO #:G126)
                                                        #:G125
                                                         (TAGBODY
                                                           (LET ((CURRENT-CHANNEL
                                                                  #:I124))
                                                             (DECLARE
                                                              (TYPE
                                                               CHANNEL-NUMBER
                                                               CURRENT-CHANNEL)
                                                              (IGNORABLE
                                                               CURRENT-CHANNEL))
                                                             (PROGN
                                                              NIL
                                                              (INCF
                                                               (AUDIO-OUT
                                                                CURRENT-CHANNEL)
                                                               (COERCE
                                                                (IF (=
                                                                     CURRENT-CHANNEL
                                                                     0)
                                                                    (*
                                                                     (COS
                                                                      #:ALPHA911)
                                                                     (SETF #:IN909
                                                                             (PROGN
                                                                              (VALUES)
                                                                              (LET ((#:INDEX134
                                                                                     (THE
                                                                                      FIXNUM
                                                                                      (INCUDINE.VUG::ASH
                                                                                       #:PHS131902
                                                                                       #:MINUS-LOBITS132903))))
                                                                                (LET ((#:G135
                                                                                       (*
                                                                                        #:AMP896
                                                                                        (PROGN
                                                                                         (SETF #:FRAC136905
                                                                                                 (*
                                                                                                  #:LODIV138906
                                                                                                  (LOGAND
                                                                                                   #:PHS131902
                                                                                                   #:LOMASK139907)))
                                                                                         (LINEAR-INTERP
                                                                                          #:FRAC136905
                                                                                          (CFFI:MEM-REF
                                                                                           #:DATA133904
                                                                                           'SAMPLE
                                                                                           (THE
                                                                                            NON-NEGATIVE-FIXNUM
                                                                                            (*
                                                                                             #:INDEX134
                                                                                             +FOREIGN-SAMPLE-SIZE+)))
                                                                                          (CFFI:MEM-REF
                                                                                           #:DATA133904
                                                                                           'SAMPLE
                                                                                           (THE
                                                                                            NON-NEGATIVE-FIXNUM
                                                                                            (*
                                                                                             (LOGAND
                                                                                              (THE
                                                                                               FIXNUM
                                                                                               (1+
                                                                                                #:INDEX134))
                                                                                              #:MASK137908)
                                                                                             +FOREIGN-SAMPLE-SIZE+))))))))
                                                                                  (SETF #:PHS131902
                                                                                          (LOGAND
                                                                                           (THE
                                                                                            FIXNUM
                                                                                            (+
                                                                                             #:PHS131902
                                                                                             #:FREQ-INC130901))
                                                                                           +PHASE-MASK+))
                                                                                  #:G135)))))
                                                                    (IF (=
                                                                         CURRENT-CHANNEL
                                                                         1)
                                                                        (*
                                                                         (SIN
                                                                          #:ALPHA911)
                                                                         #:IN909)
                                                                        (THE T
                                                                             +SAMPLE-ZERO+)))
                                                                'SAMPLE))
                                                              (VALUES))))
                                                         (PSETQ #:I124
                                                                  (1+ #:I124))
                                                        #:G126
                                                         (IF (>= #:I124
                                                                 *NUMBER-OF-OUTPUT-BUS-CHANNELS*)
                                                             NIL
                                                             (GO #:G125))
                                                         (RETURN-FROM NIL
                                                           NIL))))
                                                   (VALUES))))
                 (VALUES (INCUDINE.VUG::DSP-INIT-FUNCTION #:DSP912)
                         (INCUDINE.VUG::DSP-PERF-FUNCTION #:DSP912)))))))))))

The generated code is divided in the follow parts:

The FREE-DSP-INSTANCES function is useful to free the memory pool for the instances of one or all DSPs.

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 free available memory for the allocations of SAMPLE type used inside the code generated by DSP!. We can set the size of the relative memory pool by changing the value of *FOREIGN-SAMPLE-POOL-SIZE* in $HOME/.incudinerc (the default is 64MB).

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

DESTROY-DSP is useful to completely remove a DSP and all the associated memory.

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* is *STANDARD-OUTPUT* and *LOGGER-FORCE-OUTPUT* is T by default.

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

LOGGER-TIME is useful to show the time of the message. The possible values for LOGGER-TIME are :SEC (seconds) and :SAMP (samples)

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 for the messages in the realtime thread. For example:

SCRATCH> (rt-eval () (msg warn "Don't use MSG in the rt thread!")) ; wrong
WARN: Don't use MSG in the rt thread!
NIL
SCRATCH> (setf (logger-level) :info)
:INFO
SCRATCH> (rt-eval () (nrt-msg info "Ok, NRT-MSG is good in the rt thread"))
Ok, NRT-MSG is good in the 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