Change the amp of one beat in a ring

Hi,

Is there an easier / more elegant way to change the amplitude on say every 5th beat of an 8 beat ring?
for now I am creataing a counter ring
and use an if, else statement.

(ring 1,2,3,4,5,6,7,8)
  if ctr.look != 5
    sample :drum_cymbal_closed, amp: 1
  else
    sample :drum_cymbal_closed, amp: 0.25
  end

But this looks a bit cluncky.
I would like to write something like.

r = (ring 1,1,1,1,1,1,1,1)
r.tick 
sample... if r.tick is at index 4 amp: 0.25

Hi @catsquotl
Welcome to the forum! For that specific control I would do the following:

live_loop :test do
  sample :drum_cymbal_closed, amp: [1,1,1,1,0.25,1,1,1].tick
  sleep 0.25
end

But I certainly would not call it any more or less elegant than your if condition. Also, look in Help/Lang for ‘knit’ and ‘spread’ for related functionality.

PD-Pi

You could use
(knit 1,4,0.25,1,1,3)
or
if (spread 1,8).rotate(-4)

1 Like

I like David’s .rotate(-4); but here’s another way - without using an array, just a tick counter:

live_loop :tik do
  if tick % 8 == 4
    sample :drum_cymbal_closed, amp: 0.25
  else
    sample :drum_cymbal_closed, amp: 1
  end
  sleep 0.5
end

PD-Pi

1 Like

Thanks, it hadn’t occurred to me to put the amplitudes in their own ring or array.

I’ll have a look an a play…

Hi! Here’s an even more compact way, using the spread function and the so-called ternary operator in Ruby:

live_loop :accent do
  sample :drum_cymbal_closed, amp: spread(1, 8).rotate(4).tick ? 1.0 : 0.2
  sleep 0.25
end

The spread function produces a ring of true and false, and the ternary operator ? : says to use the first number when it’s true, otherwise the second. Try changing those numbers to see how it behaves; you can produce a lot of interesting patterns.

The Sonic Pi core team will caution us (correctly) that this part of Ruby is not officially supported in Sonic Pi and may break with future updates. But for now, it’s awfully handy!

[edit: oops, I misread the request. this should do what you asked for.]

1 Like