Skip to content

Instantly share code, notes, and snippets.

@xavriley
Created June 10, 2014 21:15
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save xavriley/dd6b61c24c3aed28c892 to your computer and use it in GitHub Desktop.
Save xavriley/dd6b61c24c3aed28c892 to your computer and use it in GitHub Desktop.
Funky drummer with Sonic Pi
# The funky drummer
# The aim here is to experiment with
# a) sequencing drums
# b) playing with 'time feel' which is
# music-speak for how the beat feels,
# ranging from robotic (0.0 swing_time)
# to ultra funky Fresh Prince of Bel Air
# theme tune style (0.2+ swing_time)
current_bpm = 180.0
use_bpm current_bpm
define :play_kick do |vol|
sample :drum_bass_hard, amp: vol
# play :A1 # uncomment for sub rattling bass
end
define :beat do |kick, index|
# What's going on here?
# We're randomizing the loudness of
# every drum hit to make it sound a bit
# more like a human drummer.
# The -> { ... } is called a lambda in Ruby
# It only gets run when we do 'ghost.call'
# which means it'll be a *different* random
# number each time
ghost = -> { rrand(0.2, 0.3) }
normal = -> { rrand(0.4, 0.6) }
accent = -> { rrand(0.8, 0.9) }
play_kick(normal.call) if kick == 1
if [1,3,4,5,7,8].include? index
# Rand here can be really nice
sample :elec_triangle, amp: ((index % 2) == 0 ? ghost.call : normal.call ) if rand < 0.8
end
with_fx :reverb, mix: 0.5 do
# Always have snare on 2 and 4
if index == 5
sample :elec_blip, amp: normal.call
end
end
# And sometimes on the and of 4
if (index % 2) == 0
sample :drum_snare_soft, amp: ghost.call if rand < 0.1
end
end
define :swing_time do
# This is the amount of
# delay added to the offbeats
# which gives it that swing/funk feel.
# Play around with it!
swing_time = 0.1
return swing_time
end
define :play_beat do
loop do
# Two ways of modelling beats - with 0s and 1s OR with indexes
[1, 0, 0, 0, 0, 0, 1, 0].each.with_index(1) do |kick, index|
beat(kick, index)
if(index % 2) == 0
# offbeats need to be slightly late for swing
sleep (0.5 - swing_time)
else
sleep (0.5 + swing_time)
end
end
end
end
# Comment this out after the first run
# so that you can re-run and make adjustments
# the code
play_beat
@boxabirds
Copy link

As a new Sonic Pi explorer, this is a lot of fun!
Only one question: even with a B+ overclocked at 950MHz, I'm getting "Timing error: can't keep up" and eventually "thread got too far behind time". Any ideas on what I'm doing wrong?

This is with Sonic Pi 2.0RC11.

@ktbaek
Copy link

ktbaek commented May 25, 2018

Very cool! Taught me a lot.

I used some of the elements for this drum sequencer: ktbaek/sonic-pi/drum_sequencer.rb

@ekid
Copy link

ekid commented Jan 31, 2022

Very nice, I only had to change the "beat" function name, that name no longer permitted because of internal use. But love the realness of your beat :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment