Programming Those Beats!

Play the Beat With Your Melody


Let's say I have a melody like this and a drum pattern like this in separate buffers. How do I play them at the same time? I can always copy the drums from one buffer to another. Let's put them in the beginning like that and we can hear what happens when I run the code. Well that's not quite how we want it to sound right? It played the drums first and then moved on to the melody. That's because Sonic Pi executes every command from top down all the way to the last line of code. First it's stuck with the drums inside the repeat block and then it moves on to the melody below it. You could always change the code and try to make them play at the same time but that just won't be very easy. Well that's one way to go, but I can tell you there's an easier way to make it happen. You'll get to know a new command called live_loop which is used a bit like the repeat block. Like the name suggests, it's used for looping code. First let's see which part of the code we want to loop. The drums obviously! To create the loop I'll write a live_loop to the start. I'll take the repeat block away. live_loop and then I have to give it a unique name and you always have to put a colon in front of the name. I'll call this one a beat. Like the repeat block, you always have to have a do in the beginning and end in the end. Now let's listen to... Now the beat keeps on looping but we still have to make the melody loop along. So I'll write another live_loop for the melody. live_loop and once again give it a name. Remember the colon! Let's call this one a melody and put a do here then we'll go all the way to the end of the melody and write end. And run again. Nice! Well by the way, you don't have to stop the loop to change the sample inside it. I'll make it run and try to change one sample inside it to a completely different one. Let's see how it works. change this one Now we just hit run again. Beautiful. The sounds change automatically on the next round without losing a beat.

Do this

Create a live_loop that plays at least one sound. Change the sample and press run without stopping the playback! You can start with the code below.

Loop example

live_loop :trythis do
  sample :bd_ada
  sleep 1

Which one of the statements is true?

Educator notes

Live loops are a good example of concurrency in programming. Concurrency means the ability of a computer program to perform more than one task at a time.

Please notice that you should have only one use_bpm command at the top to declare the song tempo. If you put the use_bpm command inside a live_loop, only the contents of the live_loop will be affected. This can be used for creative effects but is more of an advanced technique. (Try for example two identical live_loops with different names and slightly different tempi)

#Example of two live loops with different tempi
live_loop :loop1 do
  use_bpm 120
  sample :elec_blip
  sleep 1

live_loop :loop2 do
  use_bpm 122
  sample :elec_blip
  sleep 1

Let’s Add Some Cymbals


Now that you have a basic beat going on it's time to make it more interesting with faster percussive sounds. It's a smart idea to create different rhythms in separate live_loops so you can easily change them without messing up the basic beat. Here's how you can add the hi-hat cymbals. Create a new live_loop in the same buffer where you have the basic beat and call it hi-hat. And inside the loop will write the hi-hat sample. And it's in the :drum category :drum_cymbal and closed. The closed cymbal is a short and muffled sound so it works great for faster rhythms. To make it faster than the original beat use a smaller argument for sleep. Let's try 0.5 The loop isn't exactly 4 beats long but it repeats the same short thing all the time. If the sleep value makes sense it will match with the basic beat. Alright and it sounded much more exciting already but it could still be faster. You can change the hi-hat rhythm while the code is still running. Just change the argument let's try 0.25 now I press run and it changed it, now we're talking! And what if I make it even faster can I make a loop without any sleeps? Will it be super fast? Well, I will get an error message like this: runtime error live_loop did not sleep. A live_loop goes on forever if you don't make it stop. So if Sonic Pi would not stop me from running this code my poor computer would put all its effort into playing the sample as fast as it can until the end of time. This type of situation is commonly called freezing or hanging since all the other processes on the computer are either stopped or slowed down while the loop is running. So to fix an error like this put at least one sleep command inside every loop

Do this

Make another live_loop that plays fast hi-hats with your original beat.

Crash the live_loop by removing the sleep value and then fix it!

Why is it a good idea to separate different percussive parts to different live_loops?
What happens to the program when there is a live_loop without a sleep?

Educator notes

Sometimes you may find that a learner is making a really complex live_loop with all of their sounds inside, and are struggling to make it sound the way they want. Encourage them to break the live_loops into several simpler loops to keep things more manageable.

When there is an error inside a live_loop, such as a missing sleep, it will only stop the playback of the live_loop in question. Sometimes learners have several live_loops happily running with error messages on the screen. It’s a good idea to help them understand where the errors are as they might not realize how they are affecting their compositions. Remember to look for the line number that the error message displays.

Happy Rhythmic Accidents

Do this

Experiment with different sleep values inside your cymbal live_loop. What kind of numbers give results you find interesting? What numbers don’t work so well?

Hint: You can try dividing the sleep value to get interesting results. Use a decimal number when dividing!

sleep 1/3.0

Experimentation is the key to success. It’s all too easy to get stuck in doing the same things over and over. Sometimes the best way to break free is to try something totally crazy and see what happens. With Sonic Pi you can easily try ideas that could be impossible with traditional instruments or music programs!

Educator notes

Sonic Pi is ideal for experimenting with complex rhythms as it will never play anything wrong no matter how complicated it gets.

You can encourage students to explore the mathematical ratios between two rhythms! A simple way of exploring this is having one live_loop play one sample with a sleep value of 1, and another loop where you change the sleep value. Placing two different rhythmic ratios against each other is known as a polyrhythm.


sleep 1 against sleep 0.666666 (⅔) 3:2 (triplet)

sleep 1 against sleep 0.8 5:4 (quintuplet)

When you are making divisions in Sonic Pi, it’s important to use decimal numbers. If you use only integers, the result will be rounded down to the nearest integer as well. So to get the right ratios, always use a decimal number when dividing.

There is not really a clear consensus when a rhythm is called a polyrhythm and when it’s a cross rhythm. They both mean more or less the same thing. One explanation is that when a piece of music is based on the rhythmic difference of two or more parts its a cross rhythm and if the difference is more momentary, then it’s a polyrhythm.

Give Your Loop a Break


So far you've made live_loops that play all the time. What if you want to make a section to your beat that doesn't repeat all the time. For example, a drummer will often play fast beat on the snare something like this. But they don't play it all the time, only every four bars or so. Luckily something like this is really easy to do in Sonic Pi. First I'll create a new live_loop in a buffer where I have a beat already. live_loop now give it the name :fill always start with a do and end with an end. And the fill consists of a snare sample that repeats eight times. So let's write eight times do - whoops - and also this block should end with an end. So now I have two code blocks inside each other. Here goes the sample. snare drum and I have to give it a good sleep value let's say 0.5 that should make it nice and pretty fast. Let's listen to the beat and decide when the fill should play. I have to think how many beats the loop should wait until it's time to play the fill. So let's listen. Now! So I counted three times two four so that makes 12 beats. I think I should let fill sleep for 12 beats before it plays. I just put a sleep 12 into the beginning of the fill and let's hear it. Okay it sounds pretty good but let's say I want to turn snare from the beat off for now. I could of course delete it but if I changed my mind I will have to write everything again. So you can easily tell sonic by not to run a line of code by adding the hash sign in front of the code that you want to be skipped. Here's how: this is the line where the sample is - the sample that I want to mute for now. I'll write the hash sign over there and the code turns now gray and when I run the code again you can hear it doesn't play the snare anymore. So what just happened? The hash sign tells Sonic Pi that this line is a comment. Like you might guess, comments are pieces of text meant for humans. A coder might write a comment to explain to others how the program works or just to take notes for herself. The computer will skip all commented code so you can use this feature to turn things on or off. In live_loops you can even comment code that's running and when you press run again the music will change on the go. Now it's time for you to test those longer breaks and commenting!

Do this

Create a fill in your drum beat that plays every four bars.

  • Remember that in 4/4 time one bar has a total sleep time of 4

Add a comment to the beginning of the loop with your name and a description of the beat.

  • Comments are made with the #-sign

Live code by commenting on a part of your code while it’s still running.

Comment example

#this is a comment
play 60
sleep 1
#the play below will not play
#play 67
sleep 1

Educator notes

Commenting is a really important skill in programming, as it allows us to communicate our intent to others more clearly. A good way to have your learners get familiar with the comment syntax is asking them to write their name and the name of the composition in the beginning of their code.

Some learners may try and make their beats faster by making the sleep arguments smaller. Remind them to use the use_bpm command instead.

Halving or doubling the values of sleep arguments is a musical way of creating different rhythms. Note that faster rhythms don’t necessarily mean a faster tempo!