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
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
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.
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