Custom nyquist plugin crashes audacity

When debugging the following generator, audacity crashes (debug check failure)

;nyquist plug-in
;version 4
;type generate
;name (_ "Thue Morse generator")
;action (_ "Generating Thue Morse square waves...")
;preview enabled

;control duty (_ "Duty Cycle (%)") real "" 50 0 100
;control count (_ "Samples") int ""  1 1 10000
;control iter (_ "iterations") int "" 1 1 8

(setf gap2 (truncate (* count (/ duty 100))))

(setf gap1 (truncate (/ (- count gap2) 2)))

(setf gap3 (truncate (- count (+ gap1 gap2))))

(setf parts (truncate (power 2 iter)))

(setf total (truncate (* count (* parts 2))))

(setf sa (make-array total))

(dotimes (i parts)
    (setf on -1)
    (dotimes (c iter)
      (setf bit (logand (power 2 c) i))
	    (if (!= bit 0) (if (= on -1) (setf on 1) (setf on -1)))
    )
    
    (setf j 0)
	
    (dotimes (g gap1)
        (setf (aref sa (+ (* i count) j)) 0)
        (setf j (+1 j))
    )
	
    (dotimes (g gap2)
	    (setf (aref sa (+ (* i count) j)) on)
        (setf j (+1 j))
	)
	
    (dotimes (g gap3)
	    (setf (aref sa (+ (* i count) j)) 0)
        (setf j (+1 j))
	)
)	

(sound sa)

I’m not sure what you are trying to do, but I’ve corrected a load of mistakes so that the code will at least run. Hope this helps:

;nyquist plug-in
;version 4
;type generate
;name (_ "Thue Morse generator")
;action (_ "Generating Thue Morse square waves...")
;preview enabled
;control duty (_ "Duty Cycle (%)") real "" 50 0 100
;control count (_ "Samples") int ""  1 1 10000
;control iter (_ "iterations") int "" 1 1 8

(setf gap2 (truncate (* count (/ duty 100))))
(setf gap1 (truncate (/ (- count gap2) 2)))
(setf gap3 (truncate (- count (+ gap1 gap2))))
(setf parts (truncate (power 2 iter)))
(setf total (truncate (* count (* parts 2))))
(setf sa (make-array total))

(dotimes (i parts)
  (setf on -1)
  (dotimes (c iter)
    (setf bit (logand (truncate (power 2 c)) i))
    (if (/= bit 0)
        (if (= on -1)
            (setf on 1)
            (setf on -1))))

  (setf j 0)
  (dotimes (g gap1)
    (setf (aref sa (+ (* i count) j)) 0)
    (setf j (+ 1 j)))

  (dotimes (g gap2)
    (setf (aref sa (+ (* i count) j)) on)
      (setf j (+ 1 j)))

  (dotimes (g gap3)
    (setf (aref sa (+ (* i count) j)) 0)
      (setf j (+ 1 j))))

;(sound sa) ;; "sa" is an array, not a sound
(print sa)

The code would be more readable and easier to debug without the nested loops.
Preferably, functions would be given meaningful names (such as “decimal-to-binary”), but below I’ve just used generic names.
Consider doing something like:

(defun iter1 (val)
  (dotimes (i val)
    ..some code..))

(defun iter2 (val)
  (dotimes (i val)
    ..some more code..))

;; Main loop
(dotimes (i parts)
  ...
  (iter1 value)
  (iter2 value))

In LISP syntax, that could be written as:

(if (/= bit 0)
    (setf on (- on)))

It can be useful to use PRINT and/or FORMAT commands to create debug info. For example:

;nyquist plug-in
;version 4
;type generate
;name (_ "Thue Morse generator")
;action (_ "Generating Thue Morse square waves...")
;preview enabled
;control duty (_ "Duty Cycle (%)") real "" 50 0 100
;control count (_ "s-arraymples") int ""  1 1 10000
;control iter (_ "iterations") int "" 1 1 8

;; Global variables
(setf gap2 (truncate (* count (/ duty 100))))
(setf gap1 (truncate (/ (- count gap2) 2)))
(setf gap3 (truncate (- count (+ gap1 gap2))))
(setf parts (truncate (power 2 iter)))
(setf total (truncate (* count (* parts 2))))
(setf s-array (make-array total))
(setf on -1)  ;a more descriptive name would be helpful

;; Print some debugging info to debug window
(format t "gap1: ~a   gap2: ~a   gap3: ~a~%" gap1 gap2 gap3)
(format t "parts: ~a   total: ~a~%" parts total)


(dotimes (i parts)
  (dotimes (c iter)
    (setf bit (logand (truncate (power 2 c)) i))
    (if (/= bit 0)
        (setf on (- on)))
    ; Debug: what did we set "on" to?
    (princ "On = ")(print on))

  (setf j 0)
  (dotimes (g gap1)
    (setf idx (+ (* i count) j))
    ; debug: which element is being set?
    (format t "(setf aref s-array ~a) 0)~%" idx)
    (setf (aref s-array idx) 0)
    (setf j (+ 1 j)))

  (dotimes (g gap2)
    (setf idx (+ (* i count) j))
    ; debug: which element is being set?
    (format t "(setf aref s-array ~a) ~a)~%" idx on)
    (setf (aref s-array idx) on)
      (setf j (+ 1 j)))

  (dotimes (g gap3)
    (setf idx (+ (* i count) j))
    ; debug: which element is being set?
    (format t "(setf aref s-array ~a) 0)~%" idx)
    (setf (aref s-array idx) 0)
      (setf j (+ 1 j))))

;(sound s-array) ;; "s-array" is an array, not a sound
(print s-array)