Steve Reich's Clapping Music

Here’s an example of Steve Reich’s Clapping Music. After convincing myself not to quit Sonic Pi due to lack of a :clap sample (I joke), I settled on using a snap and a tom because I liked the contrast - similar to how two clappers might have different tones depending on how they clap / slap / cup their hands together.

According to Wikipedia this is usually performed with 8 or 12 bars per pattern until clapper two shifts, but that gets a little too repetitive for my taste so I’ve been enjoying 2 or 4.

clapping_rhythm = 'xxx-xx-x-xx-'

# How many times to play each pattern before clapper two shifts it by one beat
bars_per_pattern = 2

# As the BPM goes up (and lacking some sample mixing), it becomes harder to
# hear the interplay between the two patterns
use_bpm 45

in_thread do
  
  shifts = 0
  
  # Cycle through the rhythm pattern:
  #   Once for each beat in the rhythm,
  #   Repeated number of times specified in `bars_per_pattern`
  (clapping_rhythm.length * bars_per_pattern).times do |bars|
    
    # Play through one bar of the rhythm
    (clapping_rhythm.length).times do |clapper_one|
      # Use modulo operator so we can treat the string characters like a ring and wraparound
      clapper_two = (clapper_one + shifts) % clapping_rhythm.length
      if clapping_rhythm[clapper_one] == 'x' then
        sample :perc_snap
      end
      if clapping_rhythm[clapper_two] == 'x' then
        sample :drum_tom_hi_hard
      end
      sleep 0.125
    end
    
    # Check if it is time to shift the pattern
    if (bars + 1) % bars_per_pattern == 0 then
      shifts += 1
    end
  end
end
3 Likes

Here is a two thread version with each clapper running in a different thread:

clapping_rhythm = 'xxx-xx-x-xx-'
bars_per_pattern = 2

in_thread do
  (clapping_rhythm.length * bars_per_pattern).times do |bars|
    (clapping_rhythm.length).times do |clapper_one|
      if clapping_rhythm[clapper_one] == 'x' then
        sample :perc_snap
      end
      sleep 0.125
    end
  end
end

in_thread do
  shifts = 0
  (clapping_rhythm.length * bars_per_pattern).times do |bars|
    (clapping_rhythm.length).times do |clapper_one|
      clapper_two = (clapper_one + shifts) % clapping_rhythm.length
      if clapping_rhythm[clapper_two] == 'x' then
        sample :drum_tom_hi_hard
      end
      sleep 0.125
    end
    if (bars + 1) % bars_per_pattern == 0 then
      shifts += 1
    end
    
  end
end
3 Likes

Nice. Personally I prefer using the same sample :perc_snap for each, but using the :pan opt to separate them in the audio spectrum. make one pan: -1 the other pan: 1 (or +/- 0.8 if you dont; want them so extreme). I think this gives a bitter sense of the cross rhythms.

Hi @perpetual_monday,

that’s a nice one!

Years ago I used this version by William Denton for a Sonic Pi presentation and had some fun by using it as a start for a variation to show how easy things like that can be done in SP.

Another example of how different you can approach a musical challange …

2 Likes

Hi,

About claping music, Divine Comedy pay tribute to Philip Glass and Steve Reich

Nice coding!
Yesterday I’ve tried my own phasing composition. By now it works for a 10 notes theme but it shouldn’t be complicated to generalize it (suggestions/critics/corrections welcome). It’s my first code, I came to Sonic Pi a couple of days ago, hope you like it:

#O NOSO PHASING
use_bpm 120
live_loop :base do
  t=0.5
  play_pattern_timed [:g4,:c5,:d5,:g5,:a5,:e5,:c5,:a4,:f5,:e5],[t],pan:-1
end

live_loop :phasing do
  10.times do
    t=0.5
    play_pattern_timed [:g4,:c5,:d5,:g5,:a5,:e5,:c5,:a4,:f5,:e5],[t],pan:1
  end
  
  5.times do
    t=0.495
    play_pattern_timed [:g4,:c5,:d5,:g5,:a5,:e5,:c5,:a4,:f5,:e5],[t],pan:1
  end
end