Adding swing to patterns

Hi all. I’m looking at different ways of adding swing to rhythms. I note that there is a ‘with_swing’ method, but I don’t think it does what I usually think of as swing. I’ve found other examples of drum machines with swing, but I want to look for general solutions.

I’ve coded up the following which creates a ring of 16th note positions. at commands can then be used to schedule drum hits (or other notes) at the correct position in a bar by indexing into the ring, as per the example drum loop.

This appears to be, once I have the function, a reasonably easy way to find the right times to play notes. Finding the right lengths of notes is going to be more tricky, but I can create a ring of rings to solve that. I think.

Is the following code correct? I’m swinging the 8ths, and then creating the 16ths as equal halves of eighths. But, should I be splitting the 8ths into 16ths unequally as well?

The results of this sound plausibly correct to me, but I’m not sure.

swing = use_bpm 120
use_debug false

#
# calculate and return a ring representing the positions
# of 16th notes in a 4/4 bar with a defined amount of
# swing. 0 = no swing, 1 = shuffle
#

define :swing do |swing|
  
  ret = (ring )
  
  time = 0
  
  4.times do
    length1 = 0.5 + (0.1666 * swing)
    length2 = 1 - length1
    
    bit = (ring time, time+length1/2, time+length1,
           time+length1+length2/2 )
    ret = ret + bit
    time = time + 1
  end
  
  return ret
end

# uncomment one and execute to hear what a
# different amount of swing sounds like

## set :pattern, swing( 0 )
## set :pattern, swing( 0.1 )
## set :pattern, swing( 0.2 )
set :pattern, swing( 0.5 )
## set :pattern, swing( 0.75 )
## set :pattern, swing( 1 )

print get :pattern

#
# drum pattern so that we can hear the swing.
#

live_loop :drums do
  p = get :pattern
  
  at [ p[0], p[4], p[8], p[12] ] do
    sample :bd_haus
  end
  
  at [ p[4], p[12], p[9] ],
  [ 1, 1, 0.5] do |a|
    sample :sn_dolf, amp: a
  end
  
  at [ p[0], p[2], p[4],
       p[5],
       p[6], p[8], p[10],
  p[12], p[14], p[13] ] do
    sample :drum_cymbal_closed
  end
  
  sleep 4
end
2 Likes

Hey,

I think you can do the same thing with this code, unless I’m missing something?

use_bpm 120

live_loop :drums do ; tick
  
  with_swing 0.04, pulse: 16 do
    sample :bd_haus if bools(1,0,0,0).look
    sample :sn_dolf, amp: line(0.5, 1, steps: 16).look if bools(0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0).look
    sample :drum_cymbal_closed if bools(1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0).look
  end
  
  sleep 0.25
end

You could also use a ring or line to setup a swing pattern if you’re looking for more complex grooves I guess:

with_swing (ring 0.04, 0.05, 0.07, 0.03).look, pulse: 8 do
end
#or
with_swing (line 0, 0.05, steps: 4).look, pulse: 8 do
end
1 Like

Yes, that’s an interesting suggestion. I’ll have a play with it.

I was looking into this a bit more as I use with_swing in my own creations and found that you are right - if all the events are nested in the ‘with_swing’ block only one of them gets ‘swung’. Also, specifying more than a pulse of 4 seems to stop it swinging as well (bug perhaps).

I then had a read of the manual and it looks like you have to use different ticks for with_swing, alternatively, you can use time_warp.

use_bpm 130
use_random_seed 20190517

live_loop :drumsTimeWarp do ; tick
  stop
  snares = (ring 0,0,0,0, 0.9,0,0,0, 0,0,0,0, 1,0,0,0)
  
  time_warp (ring 0, 0.01).look do
    sample :bd_ada, amp: rrand(0.9, 1) if bools(1,0,0,0, 0,0,0,1, 0,0,0,0, 0,0,0,0).look
  end
  
  time_warp (line 0, 0.04, steps: 16).look do
    sample :sn_dolf, amp: snares.look if snares.look > 0
  end
  
  time_warp (line 0, -0.03, steps: 8).look do
    sample :elec_ping, amp: rrand(0.4, 0.5) if bools(0,0,1,0, 0,0,0,1, 0,0,1,0, 0,0,1,0).look
  end
  
  sleep 0.25
end

# swing with_swing
live_loop :drumsSwing do ; tick
  #stop
  snares = (ring 0,0,0,0, 0.9,0,0,0, 0,0,0,0, 1,0,0,0)
  
  with_swing 0.01, tick: :a do
    sample :bd_ada, amp: rrand(0.9, 1) if bools(1,0,0,0, 0,0,0,1, 0,0,0,0, 0,0,0,0).look(:a)
  end
  
  with_swing 0.01, tick: :b do
    sample :sn_dolf, amp: snares.look(:b) if snares.look(:b) > 0
  end
  
  with_swing 0.01, tick: :c do
    sample :elec_ping, amp: rrand(0.4, 0.5) if bools(0,0,1,0, 0,0,0,1, 0,0,1,0, 0,0,1,0).look(:c)
  end
  
  sleep 0.25
end
1 Like

Thank you. I’ll look into this more later.