;; markov-weights.sal -- use get-next-node in a score
;; (c) 2008 by Roger B. Dannenberg
;;
;; Revised Feb. 2024 to correct a mistake. Here is a revised
;; description, replacing text on page 175 of Algorithmic
;; Composition:
;;
;; The weight pattern is 10, 10, 10, 10, 10, 0.1, 0.1, 0.1,
;; 0.1, 10, 10, 10, 10, 10, .... This is created by first
;; making a cycle pattern that returns 10, 0.1, 10, 0.1, ...,
;; but the period length of this pattern is 2. We want to
;; split these periods into periods of length 1 and repeat
;; each period 5 times. The original version of this code
;; attempted to get period lengths of 1 using a for: keyword
;; in make-cycle. This does create period lengths of 1, but
;; it also restarts the cycle every period, so the resulting
;; sequence is just 10, 10, 10, ..., and 0.1 is never output.
;;
;; Instead of for:, we use make-length to break the length-2
;; patterns of make-cycle into length-1 patterns. Then, we
;; use make-copier to copy each pattern (a single number) 5
;; times, giving us the desired overall sequence.
;;
;; (Continue in the textbook from "The weight pattern,
;; w-pattern ...")
;;
;; Notice that the output consists of alternating octaves
;; (when w-pattern produces 10) followed by mostly-repeated
;; pitches (when w-pattern produces 0.1). You can get a
;; stronger sense of this by changing the repeat: parameter
;; from 5 to 20, and the score-len: parameter from 50 to 100.
begin
with w-pattern =
make-copier(make-length(make-cycle({10 0.1}), 1),
repeat: 5),
markov-pattern = make-markov(
list(
list(quote(c4), quote(->), quote(c4),
list(quote(c5), w-pattern)),
list(quote(c5), quote(->), quote(c5),
list(quote(c4), w-pattern))),
past: {c4}, produces: :eval)
exec score-gen(save: quote(markov-weights),
score-len: 50,
pitch: next(markov-pattern),
vel: 100, ioi: 0.2)
end
exec score-play(markov-weights)