< Back to IRCAM Forum

LISP code produces "unbound variable" error

Greetings from Tucson, Arizona!

I am working on an internal lambda function in LISP to exchange chords in a voice object with a different list of chords according to sections of the total duration. My understanding of LISP is limited, and I’m stuck on an issue that I can’t seem to solve.

function:

(lambda (chords chords-to-imbue durations section-durations chords-per-section)
(let ((total-section-dur 0)
(section-index 0)
(cps-index 0)
(prev 0)
(last 0)
(current-chords-to-imbue-segment (subseq chords-to-imbue 0 (nth cps-index chords-per-section))))
(loop for i from 0 below (length chords) do
(let ((dur (first (nth i durations))))
(setf total-section-dur (+ total-section-dur dur))
(let ((imbue-index (mod i (length current-chords-to-imbue-segment))))
(setf (nth i chords) (nth imbue-index current-chords-to-imbue-segment)))
(when (>= total-section-dur (nth section-index section-durations))
(setf prev (+ prev (nth cps-index chords-per-section)))
(incf cps-index)
(setf total-section-dur 0)
(incf section-index)
(if (null (nth cps-index chords-per-section))
(setf last (1- (length chords-per-section)))
(setf last (nth cps-index chords-per-section)))
(setf current-chords-to-imbue-segment (subseq chords-to-imbue prev (+ prev (nth cps-index chords-per-section)))))))
chords))

Inputs:

chords: ((6000) (6000) (6000) (6000) (6000) (6000) (6000) (6000) (6000) (6000) (6000) (6000) (6000))

chords-to-imbue: ((6100) (6200) (6300) (6400) (6500) (6600))

durations: ((4000) (4000) (4000) (4000) (4000) (4000) (4000) (4000) (4000) (4000) (4000) (4000) (4000))

section-durations: (16000 8000 20000 8000)

chords-per-section: (1 2 2 1)

Expected Output:
((6100) (6100) (6100) (6100) (6200) (6300) (6400) (6500) (6400) (6500) (6400) (6600) (6600))

Error message:
Error while evaluating the box imbueChordsAlongSections : The variable cps-index is unbound.

I can’t figure out why cps-index (which stands for “chords per section index”) comes up as unbound when it is bound like every other variable. It is worth noting that I also wrote this code in javascript, and it works with the given inputs.

Thank you in advance for any help with this!

Update: I solved it. In case anyone is wondering (or would like to try this function themselves), here is the correct version:

(lambda (chords chords-to-imbue durations section-durations chords-per-section)
(let ((total-section-dur 0)
(section-index 0)
(cps-index 0)
(prev 0)
(last 0)
(current-chords-to-imbue-segment (subseq chords-to-imbue 0 (nth 0 chords-per-section))))
(dotimes (i (length chords))
(let ((dur (nth 0 (nth i durations))))
(setf total-section-dur (+ total-section-dur dur))
(let ((imbue-index (mod i (length current-chords-to-imbue-segment))))
(setf (nth i chords) (nth imbue-index current-chords-to-imbue-segment)))
(when (and (< section-index (length section-durations))
(>= total-section-dur (nth section-index section-durations)))
(setf prev (+ prev (nth cps-index chords-per-section)))
(setf total-section-dur 0)
(incf section-index)
(if (>= cps-index (1- (length chords-per-section)))
(setf cps-index 0)
(incf cps-index))
(setf current-chords-to-imbue-segment
(if (< prev (length chords-to-imbue))
(subseq chords-to-imbue prev (min (+ prev (nth cps-index chords-per-section)) (length chords-to-imbue)))
nil)))))
chords))