Stutter / beat repeat


#1

Hi, this is my first post and I’m also very new to live coding or even coding for that matter.
I first stumbled upon Tidal Cycles and then Sonic Pi. I actually prefer Sonic Pi as it has many things implemented in more straightforward way. There is however a thing that I find Tidal is especially good at, and being a newb, I wonder how you would approach the same thing in Sonic Pi.
The thing is about making beat repeats or stutter. In Tidal you simply multiply / divide chosen beat and bam.
To be more precise here is a link to a tutorial for Tidal:
https://www.youtube.com/watch?v=-OiFJeSGh8o&list=PLCBw4oQTHsrD_Pe985ABIMKN-z5Ad54D7&index=2

here, if you skip to about 6:00 you will clearly see what I mean.

So, my question is: how would you approach this problem in Sonic PI?

Thanks :smile:


#2

Hi,

not exactly sure what you want to achieve (in musical terms) but you might want to have a look at spread and at; you can find some examples which tackle the question how to create drum beats in a more or less effective way here:

I think that goes into the direction you are asking.


#3

Hi martin,

I think our friend is asking a simpler question… how to speed up
or slow down things… for example a high-hat in a drum set…

Though if I’m wrong, I’m sure he’ll let us know.

Eli…


use_bpm 90

live_loop :beats do
  sleep 4
end

live_loop :loopy do
  sync :beats #<= this forces the sample to wait till 'beats' is next cued...
  sample :bd_haus
  sleep 0.1
end


live_loop :loopy1 do
  sample :drum_cymbal_closed
  sleep 0.5 #<= This loop will free-wheel, its speed depends on the amount
  # of time you set the sleep to.... (try changing it to 0.5)
end

And this one would produce a more random. ‘stuttering’ effect…

live_loop :loopy2 do
  sample :drum_cymbal_closed
  sleep [0.25,0.5].choose #<= This loop will produce a 'random' hh... 
end

#4

Guys thank you for the answers :slight_smile:

Hi Eli,
this is not exactly what I’m after…
I’ll try to explain:
in a pattern of 4/4 like: BD BD BD BD, how do I make, for example the second, BD to be not a quarter note but for example 2 eights or 4 sixteens. still keeping the 4/4 global measure. It’s sort of note repeat effect. In Tidal it would look like this: BD, BD*2, BD, BD. If I used division, like: BD, BD/2, BD, BD then the second base drum would play every second loop.
I hope this makes sense…

Martin, I’ll be digging throuh resources you provided a bit later. Thank you :slight_smile:


#6

Well, the obvious way to acomplish that (and not at all Tidal like) is probably to work with a pattern and tick:

live_loop :rhythm do
  #ptn = (ring 1,0,0,0,  1,0,0,0,  1,0,0,0,  1,0,0,0)
  #ptn = (ring 1,0,0,0,  1,0,1,0,  1,0,0,0,  1,0,0,0)
  ptn = (ring 1,0,0,0,  1,1,1,1,  1,0,0,0,  1,0,0,0)
  sample :drum_cymbal_closed, amp: ptn.tick if ptn.look > 0
  sleep 0.25
end

In the example I did not use the amp option but it is a good way to give the rhythm some dynamic qualities like:

  ptn = (ring 1,0,0,0,  1,0.5,0.25,1,  1,0,0,0,  1,0,0,0)

But I guess you were looking for something easier like the Tidal way, right? Maybe there are others with better ideas.

Plus: I am always looking for firstly easy to remember (not too much programming :wink: ) and secondly performance sparing solutions. In my experience (or better the experience of my laptop) it is quite a lot of work for a processor to run e. g. 4 live loops with a run time of 0.25 (let’s say at the bpm of 120) to just deliver a few sounds while using tick. That is why I have been experimenting with at (assuming that this would lower the work for the processor). In the end for me it all depends on the musical idea I try to get across…


#7

Okay… yeah, I’m still not quite getting what you want, but that sounds more like the ‘one_in’ command?

Eli…

live_loop :loopy2 do
  sample :drum_cymbal_closed
  sleep 1
  if one_in(2) then
    sample :drum_cymbal_closed
  end
  sleep 1
  sample :drum_cymbal_closed
  sleep 1
  sample :drum_cymbal_closed
  sleep 1
end

#8

Well, this is some swiftly working community :slight_smile:

I’m not evan that fast or able to check all your solutions right now. Anyway, I’ll be definitely trying them out and studying to find my own tricks, as well. As you know I’m really new to this game. Just trying to achieve sort of MPC style rolls

Thank you guys :+1:


#9

More than welcome matey… nice thing about these forums, is just
about everyone remembers being ‘new’. :slight_smile:

have fun.

Eli…


#10

in a pattern of 4/4 like: BD BD BD BD, how do I make, for example the second, BD to be not a quarter note but for example 2 eights or 4 sixteens. still keeping the 4/4 global measure. It’s sort of note repeat effect. In Tidal it would look like this: BD, BD*2, BD, BD.

I came up with this to achieve that effect. ‘d’ is the variable for how many times you want the BD to play in a beat, so 2 would be two eighth notes, 4 would be four 16th notes, but it worked well with any number and produces that “MPC roll” effect you mentioned. The ‘i’ is the count for what beat you are on so if you’d rather the effect on beat 3 or 4, just change the value in the if statement. Doesn’t really work to skip beats but I suppose if you wanted something to happen every other measure, you could change the 4.times to 8.times.

d = 4.0
live_loop :bd do
  4.times do |i|
    if i == 2
      d.times do
        sample :bd_sone
        sleep 1 / d
      end
    else
      sample :bd_sone
      sleep 1
    end
  end
end

#11

I think this is a candidate for the built in density command (read what it does in the help file lang section)

define :pl do #function plays sample once plus sleep
  sample :bd_klub
  sleep 1
end

live_loop :stutter do
  pl
  density 2 {pl}
  pl
  pl
end

I used shorthand for the block after density
could be written out
density 2 do
pl
end

Also if you want 1/8th notes just change the density 2 to density 4


#12

I really do like the idea, that you start with a problem (let’s say: a musical one which does not naturally belong in the domain of programming) and can come up with several solutions - depending on what’s working best for you: more or less abstract, automatic or manual, short and concise or long and easy readable …

Thanks Robin for that extension!


#13

Very nice use of density Robin, but the {pl} wouldn’t
wotk for me so I ended up as:

use_bpm 90
define :pl do #function plays sample once plus sleep
  sample :bd_klub
  sleep 1
end

live_loop :stutter do
  pl
  density 2 do
    pl
  end
  density 4 do
    pl
  end
  pl
  pl
end

#14

OK Eli. I found in cetain circumstances it wasn’t working for me either, so the full writing out of the code is probably better.
The thread got me going playing with this further.
here is one bit of code I tried out.

define :pl do |s,p=0|
  sample s,pan: p
  sleep 1
end
define :chos do
  return [:bd_haus,:bd_sone,:bd_klub,:drum_snare_soft,:drum_cymbal_closed].choose
end
live_loop :stutter do
  use_bpm 120
  s=chos
  pl(chos,-1)
  density ([2,3,4].choose) do
    sample chos,pan: -1
    sleep 1
  end  
  density ([2,3,4].choose) do
    sample chos,pan: -1
    sleep 1
  end  
  pl(chos,-1)
end

live_loop :stutter2 do
  use_bpm 120
  s=chos
  pl(s,1)
  pl(s,1)
  density ([2,3,4].choose) do
    sample chos,pan: 1
    sleep 1
  end
  density ([2,3,4].choose) do
    sample chos,pan: 1
    sleep 1
  end

#15

All good stuff! I think density is the way to go for this effect at the moment, although I did prototype a pattern syntax to make this easier. It’s the stuff that I was demoing in the Amen break slicing video here https://youtu.be/xr8HcUIBLM0?t=5m2s

I’ve had some thoughts recently about this that it would be better to turn the pattern into a ring so that you can just tick through it, instead of it being a method that handles playback etc. This should work nicely now that we have a slice: arg on sample.


#16

Ok, so I was experimenting on my own to sort of reproduce the idea I took from Tidal. Turned out not to be very difficult. After all it’s just nesting loops. Not yet sure how to achieve “divisions” like something playing every n’th time, but multiplications sure work fine:

live_loop :drumz do
  2. times do
    sample :drum_heavy_kick
    sleep 0.25
    
    12.times do
      sample :drum_cymbal_closed, amp: 0.5
      sleep 0.0175
    end
    
    2.times do
      sample :drum_snare_soft
      sleep 0.25
      sample :drum_bass_hard
      sleep 0.5
    end
    
    2.times do
      sample :drum_bass_hard
      sleep 0.5
      
      12.times do
        sample :drum_cymbal_closed, amp: 0.5
        sleep 0.0125
      end
    end
  end
  
  live_loop :hihat do
    sample :drum_cymbal_closed, amp: 0.5
    sleep 0.33
  end
  
  sample :drum_snare_soft
  sleep 1
  12.times do
    sample :drum_cymbal_closed
    sleep 0.0175
  end
end

#17

You could use slices. Might not work exactly as you need but it could come to a pretty close approximation.