Hi! Yesterday I was listening to the Rational Melodies by the minimalist composer Tom Johnson. Now I’m thinking how can I write the code for the first piece:
As you can see, there’s only a few notes, repeated almost equally, but with a little change in each measure (the rests change their place). How could I write a code to play it with the option of changing the notes? Thanks!
I recently came across a solution to this again, that I’d made a while ago and forgotten about. Here’s another way you could approach it:
# change the melody notes as desired
ns = (ring :d3, :a3, :b3, :fs4, :b3, :a3)
# 7 sequences, each made up of...
7.times do
# ...7 bars
7.times do
# rotate the position of the rest note 'triggers' every time we play a
# new bar of 8 notes
rest_bools = (bools 0, 1, 0, 0, 0, 0, 0).rotate(-tick(:rotate))
# on the last bar of every melody sequence,
# (index 6 when starting from 0),
# the number of rest triggers vs notes changes,
# and we reset to start counting the bars of the next melody sequence again.
if look(:rotate) == 6
rest_bools = (bools 0, 1, 1, 1, 1, 1, 1)
tick_reset(:rotate)
end
rest_bools = rest_bools + (bools 1)
8.times do
# 2 counters to track the next items in the melody notes
# and the rest note triggers. Both counters count up regardless of
# whether the next 'note' to play is melody or a rest.
tick
tick(:rest)
note = ns.look
# if the next item in the rest note triggers is true / 1,
# make the note to play a rest, and change the melody note counter
# using tick_set so that the next melody note (which we want to be
# played *after* this rest) is played *next* time, instead of
# being skipped over entirely.
# tick_set(X) causes both the next 'look' *and* 'tick'
# to return X.
if rest_bools.look(:rest) == true
note = :r
tick_set(look)
end
synth :piano, note: note
sleep 0.25
end
end
end