Skip to Content

Sonic Pi Code to Remix

  • Feel free to copy and paste the following sets of code in your Sonic Pi projects. 
  • All code on this page was generated by ASU Music Education Doctoral Student, Jared O’Leary 
  • We ask that you use comments in your project to credit Jared O’Leary for any code of his that you use in your own projects
  • Return to Coding and Programming Remix Resources

Basic

Simple Beat

#========================#
# Coded by Jared O’Leary #
#   www.JaredOLeary.com  #
#========================#

# This program creates a simple, but random, beat
loop do
  # First it plays a bass drum along with four hi hat sounds (:drum_cymbal)
  sample :drum_heavy_kick
  4.times do
    # The if/else conditionals will randomly pick either the first sample or the second if the condition is not met
    # The one_in(4) means that the first sample will only occur if the computer rolls a four-sided dice and gets a one
    if one_in(4)
      sample :drum_cymbal_open, amp: 0.45, finish: 0.05
    else
      sample :drum_cymbal_closed, amp: 0.25
    end
    sleep 0.125
  end
  # The second half of this code plays a snare and plays one of the two cymbal sounds again
  sample :elec_snare
  4.times do
    if one_in(4)
      # What does finish: do to the sample?
      sample :drum_cymbal_open, amp: 0.45, finish: 0.05
    else
      sample :drum_cymbal_closed, amp: 0.25
    end
    sleep 0.125
  end
end

Simple Drums

#========================#
# Coded by Jared O’Leary #
#   www.JaredOLeary.com  #
#========================#

# This part of the code will either play a bass drum (:drum_heavy_kick) or a hi hat (:drum_cymbal_closed)
# If you change the one_in() number, this will change how likely the first part (if) will occur
# The bigger the number, the less likely it will occur
live_loop :drums do
  if one_in(2)
    sample :drum_heavy_kick
    sleep 0.5
  else
    sample :drum_cymbal_closed
    sleep 0.25
  end
end

# This part of the code will play one of two sounds
# What does the finish: do? Try changing the number to find out how you can change the sample's sound
live_loop :cymbals do
  if one_in(5)
    sample :drum_cymbal_hard, finish: 0.02
  else
    sample :drum_cymbal_soft, finish: 0.02
  end
  sleep 0.125
end

Simple Complex Rhythms

#========================#
# Coded by Jared O’Leary #
#   www.JaredOLeary.com  #
#========================#
# This program creates complicated rhythms with a small amount of code
# How does spread work? (look under Lang in the Help section)
# What happens if you change either/both of the numbers in spread?
live_loop :euclid_beat do
  sample :bd_haus, amp: 2 if (spread 1, 4).tick
  sample :elec_bong, amp: 1.5 if (spread 3, 8).look
  sample :perc_snap, amp: 0.8 if (spread 7, 11).look
  sleep 0.125
end

Simple Hot Cross Buns

#========================#
# Coded by Jared O’Leary #
#   www.JaredOLeary.com  #
#========================#

# This sets how fast the song is played
use_bpm 120

# First phrase is played twice
2.times do
  play :e, release: 2
  sleep 2
  play :d, release: 2
  sleep 2
  play :c, release: 4
  sleep 4
end

# Four repeated notes
4.times do
  play :c
  sleep 1
end

# Four more repeated notes
4.times do
  play :d
  sleep 1
end

# Our first phrase is played one last time
play :e, release: 2
sleep 2
play :d, release: 2
sleep 2
play :c, release: 4
sleep 4

Moderate

Moderate Drum Beat

#========================#
# Coded by Jared O’Leary #
#   www.JaredOLeary.com  #
#========================#

# Change the seed number to change the beat
use_random_seed 1
use_bpm 120

#============================================================================#
# Variables equate to music durations
# I do this to save time by typing one letter instead of several numbers
# q = quarter note
# e = 8th note
# s = 16th note
# t = 32nd note
# de = dotted 8th note
#============================================================================#

q = 1
e = 0.5
s = 0.25
t = 0.125
de = 0.75

# This sets the time to make sure everything lines up together
# The sleep for 4 means it will wait four beats until sending a message to the rest of the loops to start again
live_loop :time do
  sleep 4
end

# This is the loop for the bass drum
live_loop :bass do
  # The sync makes sure everything lines up
  sync :time
  4.times do
    # Using the rrand for the amp: means that it will randomly pick how loud it will be (between the two numbers given)
    sample :drum_bass_hard, amp: rrand(0.75, 1.1)
    sleep s
    # The if one_in() allows you to make this sample play only if the computer rolls a dice and happens to get one out of (n)
    # In this case it means we will only hear it if the six-sided dice rolls a one.
    sample :drum_bass_hard, amp: rrand(0.25, 1) if one_in(6)
    sleep s
    # We only hear this drum if a ten sided dice rolls a one_in
    # What happens to the beat if you change the numbers around?
    sample :drum_bass_hard, amp: rrand(0.25, 1) if one_in(10)
    sleep s
    sample :drum_bass_hard, amp: rrand(0.25, 1) if one_in(6)
    sleep s
  end
end

# This is the loop for the hi hat
live_loop :hhat do
  sync :time
  16.times do
    # The if/else conditionals will only play the first section (if) only if the dice gets one out of two
    # Otherwise it will just sleep (else)
    if one_in(2)
      sample :drum_cymbal_closed, amp: rrand(0.25, 0.6)
      sleep t
      sample :drum_cymbal_closed, amp: rrand(0.15, 0.4) if one_in(12)
      sleep t
    else
      sleep s
    end
  end
end

# This is the snare drum loop
# The snare drum loop uses all the same concepts from the previous two loops
live_loop :snare do
  sync :time
  2.times do
    sleep s
    sample :drum_snare_soft, amp: rrand(0.25, 1) if one_in(4)
    sleep de
    sample :drum_snare_soft, amp: rrand(0.6, 1)
    sleep de
    sample :drum_snare_soft, amp: rrand(0.25, 1) if one_in(4)
    sleep s
  end
end 

Moderate Guitar Drums

#========================#
# Coded by Jared O’Leary #
#   www.JaredOLeary.com  #
#========================#

# This is the loop for the bass drum and choir
live_loop :whatev do
  sample :ambi_choir, rate: 0.3, pan: rdist(1)
  sample :bd_haus, rate: 1
  sleep 0.5
end

# This is the hihat loop.
live_loop :hhat do
  # I use these variables as a ring so I don't have to write out variations for all four notes
  # A ring allows you to cycle through your options forever (in this case, there are four options I provided)
  hh_amp = (ring 0.13, 0.13, 0.6, 0.16)
  hh_rate = (ring 1, 1, 1.2, 1)

  # Using this loop, I am able to change the amp: and rate: of the cymbal for each note played
  # Notice the .tick? and .look? The .tick cycles through the ring and the .look tells the computer to look at the .tick number
  # This lets the computer know which number to use from my ring variables above.
  4.times do
    sample :drum_cymbal_closed, amp: hh_amp.tick, rate: hh_rate.look
    sleep 0.125
  end
end

# This is the loop for the guitar sounds
live_loop :guit do

  #I use two with_fx blocks to apply both effects to the first guitar sample
  # However, the second guitar sample only has one effect (:flanger)
  with_fx :flanger, feedback: 0.4 do
    with_fx :echo, mix: 1, phase: 0.25 do
      sample :guit_em9, rate: 0.5, pan: rdist(1)
    end
    # Check out what rdist does under the Lang section of Help
    sample :guit_em9, mix: 1, rate: -0.5, pan: rdist(1)
    sleep 8
  end
end

# This is the snare drum loop (with one extra bass note)
live_loop :snare do
  # What happens when you change the mix: or phase: numbers?
  with_fx :bitcrusher, mix: 0.8, phase: 0.25 do
    sleep 1.0
    # What does :rate do? What does rate: do when it's a negative number?
    sample :drum_snare_hard, amp: 0.2, rate: -1
    sleep 0.5
    sample :drum_snare_hard, amp: 0.4, rate: 2
    sleep 0.25
    sample :bd_haus, rate: 1
    sleep 0.25
  end
end

Moderate Hot Cross Buns with Percussion

#========================#
# Coded by Jared O’Leary #
#   www.JaredOLeary.com  #
#========================#

# This sets the speed/tempo/bpm of the song
use_bpm 144

# This sets how the song will sound
use_synth :tri

# This is a function that we will use three times below (instead of writing it out three times, we can use a function)
define :buns do
  play :e, release: 2
  sleep 2
  play :d, release: 2
  sleep 2
  play :c, release: 4
  sleep 4
end

# This defines what our song is and uses the "buns()" function we defined above
# Why did we define buns() above and use it down here?
define :song do
  with_fx :echo do
    buns()
    buns()
    4.times do
      play :c
      sleep 1
    end
    4.times do
      play :d
      sleep 1
    end
    buns()
  end
end

# The percussion part
# What happens if you change the numbers around in spread?
live_loop :perc do
  sample :bd_haus if (spread 1, 4).tick
  sample :elec_bong if (spread 3, 8).look
  sample :perc_snap, amp: 0.3 if (spread 9, 12).look
  sleep 0.25
end

# This calls our song and plays it with the percussion part
# You would use this if you had this song in multiple buffers. Otherwise, you could just use another live_loop
song()

Advanced

Complicated Drum Beat

#========================#
# Coded by Jared O’Leary #
#   www.JaredOLeary.com  #
#========================#

# Change the seed number to change the beat - check out 4, 14, 27, 32, 33, 42, 43
use_random_seed 27
use_bpm 120
use_debug false

#============================================================================#
# These variables equate to music durations
# q = quarter note
# e = 8th note
# s = 16th note
# t = 32nd note
# de = dotted 8th note
#============================================================================#
q = 1
e = 0.5
s = 0.25
t = 0.125
de = 0.75

# This is used to count what measure is playing (out of four)
count = 1

# This is used to set the maximum spread of the humanization effect (which determines how far off the beat each hit will land
master_unquant = 0.05

#============================================================================#
# The purpose of this live_loop is to keep track of each measure (four beats)
# The count variable will count out four measures and reset itself to one every four measures
# This will allow me to create a different groove depending on what measure it's on (count)
#============================================================================#
live_loop :time do
  sleep 4
  count += 1
  count = 1 if (count > 4)
end

#============================================================================#
# This is the code for the bass drum and some cymbal sounds
#============================================================================#
live_loop :floor do
  # The ring variables allow me to cycle through the numbers I put in them.
  # This allows me to use different numbers for each one_in() below
  bd_arr = [(ring 10, 5, 10), (ring 6, 10, 6)]

  # If the count is < 4 we will hear the first block of code, otherwise (else) we will hear the second block of code
  # This means the first three measures will be the first block (if) and the last measure will be the second block (else)
  # Part one (measures one through three)
  4.times do
    bd_unquant = rrand(0, master_unquant)
    sleep bd_unquant / 2

    # Unless means that we will hear the sample unless we roll a dice and get a one_in
    # In this case, the dice is twenty-sided and we will hear the sample unless we roll a one
    # The && count < 3 also means that we will only run this code when count equals 1, 2, or 3, but not 4
    sample :drum_bass_hard, amp: rrand(0.75, 1.1), rate: rrand(0.999, 1.001) unless one_in(10) || count > 3

    # This is the code that will run when count is 4
    sample :drum_bass_hard, amp: rrand(0.75, 1.1), rate: rrand(0.999, 1.001) if one_in(3) && count == 4
    sleep s - (bd_unquant / 2)

    3.times do
      # The .tick is used to cycle through the numbers in the ring each time this is called in the loop
      # The one_in() contains a ternary if/else statement that checks to see if count equals 4
      # If count equals 4, it will run the second part of our array (bd_arr[1])
      # Otherwise, it will run the first part of our array (bd_arr[0])
      bd_unquant = rrand(0, master_unquant)
      sleep bd_unquant / 2
      sample :drum_bass_hard, amp: rrand(0.25, 1), rate: rrand(0.999, 1.001) if one_in(count == 4 ? bd_arr[1].tick : bd_arr[0].tick)

      # The cymbals will only play when count equals 4 and we roll one_in(6)
      sample :drum_splash_soft, amp: rrand(0.25, 1), rate: rrand(0.999, 1.001), release: 0.3 if one_in(6) && count == 4
      sleep s - (bd_unquant / 2)
    end
  end
end

#============================================================================#
# This is the code for the hi hat
#============================================================================#
live_loop :hhat do
  # Same thing as above; however, I'm now using more rings
  hh_amp = (ring 0.4, 0)
  hh_arr = [(ring 20, 10), (ring 10, 12, 20, 12), (ring 5, 12), (ring 1, 8)]
  hh_r = (ring 2, 4)

  # This time I have four different blocks of code (one for each measure in a four bar phrase)
  # This will play a crash sound at the start of each four bar phrase; however, it randomly picks one of the two sounds
  if one_in(2)
    sample :drum_splash_hard, amp: rrand(0.2, 0.7), rate: rrand(0.999, 1.001) if one_in(2)
  else
    sample :drum_splash_soft, amp: rrand(0.2, 0.7), rate: rrand(0.999, 1.001) if one_in(2)
  end

  # Same idea as the code above, but with new values
  32.times do
    if one_in(2) && count > 1
      2.times do
        hh_unquant = rrand(0, master_unquant)
        sleep hh_unquant / 2
        sample :drum_cymbal_closed, amp: (rrand(0.15, 0.4) + hh_amp.tick), rate: rrand(0.999, 1.001) unless one_in(hh_arr[count - 1].tick)
        sleep t - (hh_unquant / 2)

        sleep hh_unquant / 2
        sample :drum_cymbal_closed, amp: (rrand(0.15, 0.4) + hh_amp.tick), rate: rrand(0.999, 1.001) if one_in(hh_arr[count - 1].tick) && count > 1
        sleep t - (hh_unquant / 2)
      end
    else
      hh_unquant = rrand(0, master_unquant)
      sleep hh_unquant / 2
      sample :drum_cymbal_closed, amp: (rrand(0.15, 0.4) + hh_amp.tick), rate: rrand(0.999, 1.001) if one_in(4) || count == 1
      sleep s - (hh_unquant / 2)

      hh_unquant = rrand(0, master_unquant)
      sleep hh_unquant / 2
      sample :drum_cymbal_closed, amp: (rrand(0.15, 0.4) + hh_amp.tick), rate: rrand(0.999, 1.001) if one_in(4) && count != 1
      sleep s - (hh_unquant / 2)
    end
  end
end

#============================================================================#
# This is the code for the snare drum
# Notice how I added a delay after the name?
# This makes the code simpler below by offsetting the first hit and doing a 8.times loop instead of two 4.times loops with the loud hit in the middle
#============================================================================#
live_loop :snare, delay: q do
  # Same ideas for the variables as in the blocks above; however, my array uses four different rings (one for each measure)
  # I call these different rings using count-1 (because arrays start with 0 rather than 1)
  sd_amp = (ring 0, 0.4)
  sd_arr = [(ring 20, 7, 6, 6), (ring 15, 4, 6, 5), (ring 10, 4, 8, 4), (ring 4, 3, 3, 3)]
  drums = [:drum_snare_soft, :drum_tom_lo_soft, :drum_tom_hi_soft, :drum_tom_mid_soft]

  # Measure one through four using an array to change the probability each beat will occur
  # This one is the mean drum hit I want to hear on the second the fourth beat (hence using unless so it occurs frequently)
  sample :drum_snare_soft, amp: rrand(0.6, 1), rate: rrand(0.999, 1.001) unless one_in(20)
  8.times do
    # The variable sd_unquant is used to "humanize" the drumming by providing a slight variation in the timing for the snare drum.
    sd_unquant = rrand(0, master_unquant)
    sleep sd_unquant / 2
    sample :drum_snare_soft, amp: (rrand(0.15, 0.5) + sd_amp.tick), rate: rrand(0.999, 1.001)  if one_in(sd_arr[count - 1].tick) && count < 4

    # This will pick one of the samples in the drums variable above and play it as a fill on measure four
    sample drums.choose, amp: (rrand(0.15, 0.5) + sd_amp.look), rate: rrand(0.999, 1.001)  if one_in(sd_arr[count - 1].look) && count == 4
    sleep s - (sd_unquant / 2)
  end
end 

Complicated Drum Beat No Comments

#========================#
# Coded by Jared O’Leary #
#   www.JaredOLeary.com  #
#========================#

use_random_seed 4
use_bpm 120
use_debug false

q = 1
e = 0.5
s = 0.25
t = 0.125
de = 0.75

count = 1
master_unquant = 0.05

live_loop :time do
  sleep 4
  count += 1
  count = 1 if (count > 4)
end

live_loop :floor do
  bd_arr = [(ring 10, 5, 10), (ring 6, 10, 6)]

  4.times do
    bd_unquant = rrand(0, master_unquant)
    sleep bd_unquant / 2

    sample :drum_bass_hard, amp: rrand(0.75, 1.1), rate: rrand(0.999, 1.001) unless one_in(10) || count > 3
    sample :drum_bass_hard, amp: rrand(0.75, 1.1), rate: rrand(0.999, 1.001) if one_in(3) && count == 4
    sleep s - (bd_unquant / 2)

    3.times do
      bd_unquant = rrand(0, master_unquant)
      sleep bd_unquant / 2
      sample :drum_bass_hard, amp: rrand(0.25, 1), rate: rrand(0.999, 1.001) if one_in(count == 4 ? bd_arr[1].tick : bd_arr[0].tick)

      sample :drum_splash_soft, amp: rrand(0.25, 1), rate: rrand(0.999, 1.001), release: 0.3 if one_in(6) && count == 4
      sleep s - (bd_unquant / 2)
    end
  end
end

live_loop :hhat do
  hh_amp = (ring 0.4, 0)
  hh_arr = [(ring 20, 10), (ring 10, 12, 20, 12), (ring 5, 12), (ring 1, 8)]
  hh_r = (ring 2, 4)

  if one_in(2)
    sample :drum_splash_hard, amp: rrand(0.2, 0.7), rate: rrand(0.999, 1.001) if one_in(2)
  else
    sample :drum_splash_soft, amp: rrand(0.2, 0.7), rate: rrand(0.999, 1.001) if one_in(2)
  end

  32.times do
    if one_in(2) && count > 1
      2.times do
        hh_unquant = rrand(0, master_unquant)
        sleep hh_unquant / 2
        sample :drum_cymbal_closed, amp: (rrand(0.15, 0.4) + hh_amp.tick), rate: rrand(0.999, 1.001) unless one_in(hh_arr[count - 1].tick)
        sleep t - (hh_unquant / 2)

        sleep hh_unquant / 2
        sample :drum_cymbal_closed, amp: (rrand(0.15, 0.4) + hh_amp.tick), rate: rrand(0.999, 1.001) if one_in(hh_arr[count - 1].tick) && count > 1
        sleep t - (hh_unquant / 2)
      end
    else
      hh_unquant = rrand(0, master_unquant)
      sleep hh_unquant / 2
      sample :drum_cymbal_closed, amp: (rrand(0.15, 0.4) + hh_amp.tick), rate: rrand(0.999, 1.001) if one_in(4) || count == 1
      sleep s - (hh_unquant / 2)

      hh_unquant = rrand(0, master_unquant)
      sleep hh_unquant / 2
      sample :drum_cymbal_closed, amp: (rrand(0.15, 0.4) + hh_amp.tick), rate: rrand(0.999, 1.001) if one_in(4) && count != 1
      sleep s - (hh_unquant / 2)
    end
  end
end

live_loop :snare, delay: q do
  sd_amp = (ring 0, 0.4)
  sd_arr = [(ring 20, 7, 6, 6), (ring 15, 4, 6, 5), (ring 10, 4, 8, 4), (ring 4, 3, 3, 3)]
  drums = [:drum_snare_soft, :drum_tom_lo_soft, :drum_tom_hi_soft, :drum_tom_mid_soft]

  sample :drum_snare_soft, amp: rrand(0.6, 1), rate: rrand(0.999, 1.001) unless one_in(20)
  8.times do
    sd_unquant = rrand(0, master_unquant)
    sleep sd_unquant / 2
    sample :drum_snare_soft, amp: (rrand(0.15, 0.5) + sd_amp.tick), rate: rrand(0.999, 1.001)  if one_in(sd_arr[count - 1].tick) && count < 4
    sample drums.choose, amp: (rrand(0.15, 0.5) + sd_amp.look), rate: rrand(0.999, 1.001)  if one_in(sd_arr[count - 1].look) && count == 4
    sleep s - (sd_unquant / 2)
  end
end