Best way to play notes simultaneously

Hi all,

So I have another newbie question! What would be the best and cleanest way to play multiple notes simultaneously but keep them on the same line as to control the parameters.
Trying to streamline something like this:

"live_loop :notes do
play :f3
play :a3
play :c4
play :e4
sleep 2
play :a3
play :c4
play :e4
play :g4
sleep 2
play :e3
play :g3
play :b3
play :d4
sleep 2
play :d3
play :f3
play :a3
play :c4
sleep 1
play :e3
play :g3
play :b3
play :d4
sleep 1
end
"

Hi @Eyebot,

there are several ways (thatā€™s what Ruby is famous for as far as I know :wink: ). One would be something like:

live_loop :notes do
  # this is a simple list: square brackets and items separated by commas
  play [:f3, :a3, :c4, :e4], amp: 0.5, release: 1.5
  sleep 2
  # Or you can also take a ring which is effectively the same here
  play (ring :a3, :c4, :e4, :g4), attack: 0.25, amp: 0.75
  sleep 2
end
2 Likes
live_loop :notes do
  play_chord [:f3, :a3, :c4, :e4]
  sleep 2
  play_chord [:a3, :c4, :e4, :g4]
  sleep 2
  play_chord [:e3, :g3, :b3, :d4]
  sleep 2
  play_chord [:d3, :f3, :a3, :c4]
  sleep 1
  play_chord [:e3, :g3, :b4, :d4]
  sleep 1
end
3 Likes

Thanks Martin, much appreciated!!

Thanks so much, great suggestion!

Uhh, yeah, chords is the keyword: If your note lists are ā€˜properā€™ chords (and not clusters :wink: ) you can of course do the following:

live_loop :notes do
  play (chord :f3, :major7)  
  sleep 2
  play (chord :a3, :minor7)
  sleep 2
  play (chord :e3, :minor7)
  sleep 2
  play (chord :d3, :minor7)
  sleep 1
  play (chord :e3, :minor7)
  sleep 1
end
1 Like

Funny or maybe not,

iā€™ve never noticed that play can plays chords if we pass an array or a ring.
But i think itā€™s not a good way to introduce the ring notion. In my opinion, there is no ā€œringā€ into this use of ring.
Ring is used to take an element then next then next. so itā€™s a bit weird to use ring to play chord. no ?

Hi @nlb,

well, I am very pragmatic in this respect.

I donā€™t think it is a weird use at all:

puts (chord :c, :major) # evalutates to: (ring 60, 64, 67)

And you might even want to do something like:

live_loop :notes do
  play (ring
        (chord :f3, :major7),
        (chord :a3, :minor7),
        (chord :e3, :minor7),
        (chord :d3, :minor7),
        (chord :e3, :minor7)
        ).tick
  sleep (ring 2, 2, 2, 1, 1).look
end

ok itā€™s not weird if we consider ring as a tab. Bref. And @martin youā€™re right it can be useful to know the chord sends back a ring.

play (ring :c, :f, :g)
sleep 1

play (chord :c, 'major')
sleep 1


play (chord :c, 'major')[0]
sleep 1

# arpeges
len = (chord :c,'11+').length
len.times do
  play (chord :c,'11+').tick
  sleep 0.25
end
1 Like

we can go on on arpeggio up and down since chords are ring. we can use ring functions.

puts ch = (chord :c,'11+')
puts ch_down = ch.butlast.reverse

# the go

(ch.length).times do
  play ch.tick
  sleep 0.25
end

# and the back
tick_reset
ch_down.length.times do
  play ch_down.tick
  sleep 0.25
end

and of course as scale are rings

puts ch = (scale :c, :augmented)
puts ch_down = ch.butlast.reverse

Yes, very true.

And finally, hereā€™s a short version of the original code:

live_loop :notes do
  play (chord
        (ring :f3, :a3, :e3, :d3, :e3).tick,
        (knit :major7, 1, :minor7, 4).look)
  sleep (ring 2, 2, 2, 1, 1).look
end
1 Like

Hi. Is there any benefit to creating the ring outside the live_loop, so that a new one isnā€™t instantiated each time?

I guess it saves a bit of time, but primarily you do it when more than one loop needs to access the ring (or any other data.)