It was pretty close. You’ll notice there’s a square bracket that should be a round bracket in the chords array.
Also, the parameters for the chord_invert fn were not quite right. Lastly, if your intention is to play the chords as actual chords instead of each individual note, the tick(:cho) was unnecessary - the .each already steps through the list of chords.
As for optimisation, others may have different ideas, but here’s my two cents:
I have used chords.tick(:cho) instead of chords.each since this is more idiomatic Sonic Pi syntax (though by no means is it absolutely necessary). However, in order to make chords.tick(:cho) work properly, we then need to make chords a ring, instead of an array, as ticking past the end of an array will return nil, whereas ticking past the end of a ring will loop back to its beginning (assuming that’s what we want).
# Playing a Chord Progression
# Note Durations
w = 4
h = 2
q = 1
e = 0.5
s = 0.25
r = 0.25
use_synth :tri
use_synth_defaults attack: 0.05, sustain: 0.5, release: 0.75,
cutoff: 80,amp: 0.5
use_octave 1
chords = (ring
(chord_degree :i,:A3,:minor,3),(chord_invert (chord :G3,:major),1),
(chord_degree :iv,:D4,:minor,4),(chord_degree :i,:A3,:minor),
)
dur = (knit w,4)
live_loop :chords do
use_bpm 100
play chords.tick(:cho)
sleep dur.tick(:dur)
end