Making Music with Code: Composition & Live Performance with Sonic Pi | Steve Lydford | Skillshare

Playback Speed


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Making Music with Code: Composition & Live Performance with Sonic Pi

teacher avatar Steve Lydford, Music, Sound Design and Productivity

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

    • 1.

      Course overview

      1:56

    • 2.

      Introduction

      1:06

    • 3.

      Getting Sonic Pi

      1:11

    • 4.

      Getting to know the Sonic Pi user interface

      8:48

    • 5.

      Lets make some noise!

      5:07

    • 6.

      Using MIDI note names

      2:54

    • 7.

      Code comments

      2:49

    • 8.

      Using the log

      0:44

    • 9.

      Play options

      6:14

    • 10.

      Setting the tempo

      1:49

    • 11.

      Synths

      2:52

    • 12.

      Applying synth filters

      4:40

    • 13.

      Envelopes

      8:47

    • 14.

      Playing samples

      12:11

    • 15.

      Program flow

      2:01

    • 16.

      Loops

      6:12

    • 17.

      Nested loops

      3:59

    • 18.

      To infinity, but not beyond!

      1:58

    • 19.

      Enhancing your beat

      0:50

    • 20.

      Randomisation

      4:23

    • 21.

      Generating melodies with randomisation

      3:37

    • 22.

      Other random functions

      2:24

    • 23.

      Selection

      6:17

    • 24.

      if ... else

      3:40

    • 25.

      Combining comparisons

      2:38

    • 26.

      The one_in randomisation function

      3:28

    • 27.

      The simple if

      2:45

    • 28.

      Variables

      5:53

    • 29.

      Loop counters

      4:46

    • 30.

      Lists

      5:13

    • 31.

      Indexes

      6:19

    • 32.

      Making a drum sequencer

      11:22

    • 33.

      Playing patterns

      4:26

    • 34.

      Chords

      7:01

    • 35.

      Scales

      6:16

    • 36.

      Rings

      4:54

    • 37.

      Ring functions

      5:36

    • 38.

      Custom functions

      6:48

    • 39.

      Function parameters

      4:52

    • 40.

      Effects in Sonic Pi

      2:52

    • 41.

      FX options

      2:00

    • 42.

      Chaining effects

      1:29

    • 43.

      Taking control

      5:29

    • 44.

      Controlling note slide

      0:58

    • 45.

      Controlling effects

      4:38

    • 46.

      Live loops

      8:28

    • 47.

      Live performance with live loops

      7:09

    • 48.

      MIDI in

      11:54

    • 49.

      MIDI out

      4:54

    • 50.

      Live audio

      7:15

    • 51.

      Wrapping up

      3:27

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

67

Students

1

Projects

About This Class

Aimed at musicians with little or no coding experience, this fun course will teach you how to compose and perform music using code as your instrument. Based on the free Sonic Pi framework, popular in the Algorave scene, you'll cover everything from the very basics of programming to using Sonic Pi for live performance, including writing a drum sequencer. Later in the course, you'll even learn how to integrate your code with MIDI & audio instruments.

With four hours of video split across fifty lectures, you will find detailed descriptions and demonstrations of:

  • How to create music by coding musical patterns with synths and samples.
  • Fundamental programming concepts, including program flow and Sonic Pi's built-in data structures.
  • Creating a drum sequencer, looping melodies, chord progressions and bass lines from scratch.
  • How to use filters and ADSR envelopes for code-based sound design.
  • How to add effects such as distortion, delay and reverb to make your sounds more interesting.
  • How to control MIDI and audio from your code.
  • How to use the features of Sonic Pi to enhance your live performances.

We'll be using the free Sonic Pi throughout the course, and by the end, you'll be able to apply what you've learned to create unique musical compositions and perform live using code. As you’ll see, anyone can learn to program. We take each new concept step-by-step, and it’s easier than you think, even if you have absolutely no prior coding experience!

Meet Your Teacher

Teacher Profile Image

Steve Lydford

Music, Sound Design and Productivity

Teacher

Hi, I'm Steve Lydford.

I am a sound designer, software engineer and author with over two decades of professional experience. I am an experienced teacher and have taught numerous courses both online and in-person.

I live with my family in a remote farmhouse in mid-Wales, UK, where I don't have to worry about soundproofing or neighbours!

If you'd like to find out more, please do [follow] my Skillshare profile, and if you've got ideas for classes that you'd find useful, drop me a message/email, and I'll see what I can do

Thanks for watching, and welcome!

See full profile

Level: All Levels

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. Course overview: Welcome to make music with code, the complete guide to code them as Sonic Pi. This fun course is aimed at musicians with little or no coding experience and will teach you how to compose and perform music using code is your instruments. My name is Steven Moffat and I'll be your instructor. I've been writing software and creating music for over 30 years. And during that time I've learned, worked in and taught over a dozen different programming languages in this course, which contains over four hours of video lessons, you'll learn how to use a hugely popular and free Sonic Pi framework. You will cover everything from the very basics of programming to use in Sonic Pi for sound design and live performance with in-depth and detailed explanations and examples. At every stage, you'll learn how to create music by coding musical patterns with since and samples. Fundamental programming concepts including program flow and Sonic Pi is built-in data structures. How to create a drum sequencer and looping melodies, chord progressions and baselines from scratch. How to use filters and ADSR envelope for code-based sound design. The use of randomization algorithms to create generative music. How to add effects such as distortion, delay and reverb to make your sounds that much more interested. You'll learn how to control midi and audio from your code and integrate them into your performances. By the end of the course, you'll be able to apply what you've learned to create unique musical compositions and perform live using code. And you'll see that anyone can learn to program. I'd take each new concepts step-by-step and it really is much easier than you think the course is aimed at musicians wishing the gain some programming knowledge using code as an instrument for composition, inspiration, recording, and live performance. You don't need any prior coding experience or deep knowledge of mathematics or computer science. Or you need is some basic musical concepts such as note, scales, chords and rhythm. And a Windows mac or Raspberry Pi computer. So join in and learn how to use code to create any music you can imagine. And perhaps even some you can't. 2. Introduction: Hi there and welcome to this course where we're going to look at using code to make music both for live performances and for our compositions. So I've assumed absolutely no prior programming knowledge at all for this course. This course is very much aimed at musicians who would like to use code to compose and to perform music, or introduce each programming concepts step-by-step. We'll take it nice and slowly and there'll be plenty of opportunity for practice. Now there are some things you should have to get the most out of the course. The first of those is a computer. Now, any Windows, mac or Raspberry Pi computer will be absolutely fine. The second thing is some basic musical knowledge. Now we're not talking advanced music theory here, but as long as you've got knowledge of notes and scales and octaves, these kind of concepts, then you'll be absolutely fine. And lastly, I would definitely recommend that you listened to the course on a good pair of headphones or a good stereo speaker setup. This is to make sure that you are able to hear the nuances of some of the changes to the sounds that we create. So with that in mind, grab yourself a coffee, and let's dive right in. 3. Getting Sonic Pi: Now the software we're going to use with this course is the fantastic Sonic Pi, which was created by Sam Aaron is become hugely popular in the algorithm scene. And it's a music framework based on Ruby, which is a programming language. Don't worry about that too much, but it might be interesting to you if you've got some pass codes and experience, Sonic Pi runs on Windows and Mac and as the name suggests, actually is designed to run particularly well on a Raspberry Pi. So let's head over to the sonic Pi website and see how we go about downloading and installing them. Here we are on the Sonic Pi website and here you can see there's buttons here to download for Windows, for Mac OS, and for Raspberry Pi. But there's so much more to this website. So I would definitely encourage you to get involved with the community. Look at the examples, read through the tutorials. There's lots of great info on here. Now, Sonic Pi is available free of charge. It's hugely popular in education for teaching kids to code. But it requires a lot of maintenance. And Sam has been doing this free of charge for years. So if you can afford it, I definitely recommend you just do scroll a little way down the website and either use patria and, or GitHub Sponsors to donate a little bit of money to Sam, whatever you can afford in order to keep this fantastic initiative going. 4. Getting to know the Sonic Pi user interface: Okay, so once you've got Sonic Pi installed, go ahead and run it and you should be presented with a screen that looks something similar to this. Don't worry if it doesn't look exactly like this. I'll be showing you how to configure the screen in this session. So let's walk through each part of the UI step-by-step. So the main part of the screen is taken up by the code window. This is where we actually type the code and this is where we can run it from two, using these buttons up here that run on the Stop button. So once we've finished with our code, once it's, once the code is complete, we can hit the Run button. And here the results. If the code is running for a long time, we want it to stop. We can press the stop button. If we want to record the output of the code, either music that regenerated with the code out to a WAV file. We can press Record button and then run the code and we'll, we'll get a audio file produced. We can save and load our code. Now by default, Sonic Pi is going to persist your code between sessions. What I mean by that is if you type some code into Sonic Pi and then quit Sonic Pi, next time you come back in, that code that you had there previously, will be there and available for you on the screen. So it's got its own built-in save mechanism. However, I wouldn't rely on that if you've got a piece of code that is, you're particularly proud of or is a piece of completed composition, or it's something that you want to share with your friends or share with somebody in the community, then definitely use, use the buttons there to save your code to make a good backup copy of it. Again, once you've got a code or a piece of code that you want to load back in a file that you want to go back in, you can just do that through the load button. Down at the bottom. We've got these numbers 0 to nine. These are different. You can think of these like tabs so that they're called buffers within, within Sonic Pi, we can think of these as separate tabs. Whenever we click the Run button, we're going to run the code within this buffer. So if I'm here at the moment, if I click run and I'm going to run the code within buffer one. If I click over here, now in buffer six, I'm going to run the code that's in buffer six only. Top right, then we've got two controls to control the size of the font in the code window. And I'll be using these later on to make the code nice and big so that you can follow along nice and easily. Let's go, Let's have a look at the rest of these over here then. So the first is the scope. So this, this this panel up here on the top right is the scope. And this by default is set as a spectrum graph. You'll see this as we start to generate some noise in the next lesson. But this can be changed through the preferences panel and I'll show you how to do that in a second. This next section here is probably the most useful, useful puddle other than the code window, and that is the log. And this is going to show you exactly what's going on as your code is running. And you can output things to the log as well to get information. So this window is particularly important. The cues panel will show you what's actually happening within Sonic Pi. This panel you'll find particularly important when it comes to live performances. Then down the bottom here across the bottom of the screen, we have the Help panel. The panel has had a huge amount of effort put into it. There are, there is a full tutorial, there's links to other articles. There are example programs to produce different types of music. There's information about the bill incense, about the built-in effects and samples. And there's information there about the language itself for you to go and look up absolutely fantastic help facilities within Sonic Pi. So please, please do have a dig around in there to switch each of these panels on and off. I can just go and hit this toggle buttons here. So I can, if I hit the Help button, the highlight is removed along with the health panel. When I click it again and the Help panel will reappear. And the same for these other three buttons up here. The one we haven't looked at is the preferences panel. In here. We can just see a whole bunch of different kind of configuration items within Sonic Pi will quickly flip through these. We won't go through every one of these in detail and we will be using them throughout the course. But I'll just take you through some of the important things are the settings that you might want to use it early on. The first of these in the Audio tab then is the main volume. And this just simply controls the output volume of Sonic Pi. But there's nothing else in here that you really need to worry about just yet. Inside IO, then you can see here that I've got a midi keyboard connected, and that's really the only interesting thing in here for now. Now, if you don't have a midi keyboard, do not worry at all. You don't need one for Sonic Pi. And in fact, we'll only be using it in a very small part of the course. But it's, it's interesting to be able to create a sense sound, for example, in midi, in sight Pi, and then play that sense with your midi keyboard or other midi input device. But we're doing that much later, but don't worry about it for now. This one you might want to play around with a bit. This is configuring the preferences for the code editor, for the code window. And you can see that I've got it set on a light theme here. I think it's nice and easy and easier for you to read on this course. But if you prefer it in dark mode, you could use that. And then there are other different window types as we go through here. I'm going to flip back to the light theme here. And in here where we can toggle panels on and off and we can toggle all the information that we want to be shown within these panels. So over here we can see that the we're showing the line numbers were showing code completion, tabs, titles, buttons, etc. I'll leave all those switched on for now, but feel free to go and configure this to be exactly how you prefer to work. Individuals, then we can look at the different types of scopes. I mentioned there are different types of scopes in here. So by default is set to the spectrum graph, but we have mono stereo charts as independent scopes. There are the graphs which illustrate phase relationships, all sorts in there. I prefer to leave mine on the spectrum graph. These are not toggle, so you can have more than one graph shown at once. But throughout this course we'll leave it on the spectrum graph, but others may be useful to you. So over on the right here we have the transparency panel, and this is controlling the transparency of the Sonic Pi interface itself. Now, by default it in 99% of cases you'll leave this set a 0. But as I mentioned earlier, Sonic Pi has become really popular in things like the algorithms seen and people are doing live performances with Sonic Pi, but they'll be up on the stage and they'll project the Sonic Pi user interface on the wall behind them or a screen behind them. And actually part of the experience, part of the performance is watching the, the person code live and hearing the music and dancing alone. So what you can do is you could, you can set the transparency of the window here and you might have some, some visual effects on video or something running in the background with Sonic Pi over the top with the transparency set down a little so that Sonic Pi is showing up over the top of the video. I'm very cool. In here. We can come in and check for updates. I leave mine as to check for updates every two weeks. But if you want to, you can go and hit the check now button and it will go and check for you right now whether you need an update. And finally in the language type, then you can go and set the language for the UI and for the tutorial. So as I said, there's a thriving and fantastically friendly community around sonic Pi. People within the community of have translated the tutorials and translated the UI. So if English is not your first language and you prefer to use your native language, then you can go and select that in. Here. I'll click on the Close button to shut this window down. One last thing I want to show you here is just this info pane. And this is going to show you a bit of a splash screen where you can get all sorts of information about Sonic Pi. And you can see here is a link to the website. There's a link to Twitter to follow for updates about Sonic Pi. I would definitely encourage you to do that. You can see here your current version is, or my current version is 4.3. Just check that you're on version 4.3 or above. If not, head over to the preferences panel and click Update to get the latest version. Okay, So that's giving you an overview of the user interface. Now it's time to make some noise. 5. Lets make some noise!: So head over to the code window here, I'm going to make the font a little bigger so that you can see it. We're going to start off with perhaps the most simple program that we can possibly imagine. So I'm just going to type straightens this Coburn note and I'm going to type the command play in. The command play is one of the commands that we can use to tell Sonic Pi to make some noise for us. So let's head over here and we can do play 60. So just type play 60 into your code window and then click the Run button. And there we are. So Sonic Pi is omitted some noise for us. So I click the Run button up here to do this, I'll do it again. But to save you reaching for the keyboard and mouse over time, you can also press Command R on a Mac or Control R on a Windows PC, and that will achieve the same thing. So let's break this down a little bit. So the command play is, as I said, one of the commands and probably the most useful command, or most used command initially to tell a sonic Pi to omit some noise. But what's the 60 about? Well, it's 60 is actually a midi note number. So the way that midi works is that there are numbers from 0 to 127, so 128 different midi notes. And each of those corresponds to a note name and normal note names. So we can see here that midi note number 60 is a C for a C note on the fourth octave. And we can look over here and we can see that actually midi note names correspond to a frequency as we know that the higher the frequency, the higher the note. So a C4 is 261.63 hertz. And then there are others on here. So we can move up and down. Each increment or decrement by one is a semitone. So from 60 to 61 takes us from a C to a C sharp. From 61 to 62 texts was two a d 263 takes us through D-Sharp that corresponds up and down there. Now I've included a full midi note char inside the resources for the course. But for now it's just important to know that we can either use a midi note number or a midi note name. And at the moment we're using midi note number 60. So when we run our code is actually playing a C in the fourth octave. So this is great and this are our first bit of sound out of, out of Sonic Pi, but it's not going to make number one. So let's add some more code. So to add another line of code, just hit return. And here I go. Let me make that a little bit bigger for you. There we go. So to add some more notes, I can just add some more play commands. So let's type in a play 64. Let's add a play 67. Let's hit Run or, or Command R. We are, so there are three notes playing all at the same time. So that is a, C and E and a G. If we look at the midi notes are a C and E energy was 606467, and that gives us a C major triad. Now, all these notes are playing at once. So what we're effectively producing here as a chord, if I want to play these notes in an ascending order, then I need to tell Sonic Pi to leave a little bit of time. I'll leave a rest between these notes. And I can do that using our next command, which is the sleep command. Now, so in-between each nodes I'm going to add a sleep one. This is telling Sonic Pi to sleep for one beat. Okay, So all of the timings within Sonic Pi or within beats. By default, the beats per minute or the BPM for a sonic Pi program is 60. So 60 beats a minute. So 60 beats per minute. If we sleep for one beat, then we are going to sleep for 1 second. So let's add another sleep here. Again for one more beat, for one more bit. And let's play it. And there we are. There's our 33 notes major triad, but this time arpeggiated, playing one note after another rather than as a single cord. So I can put anything I want to in terms of the sleep pair. So I could change these to sleep for two. And this is going to sleep for two beats. Or I could sleep for fractions of a second as well. So I can sleep for half, half a beat or half a half a second because we're at 60 beats per minute. And I'll show you how to change the beats per minute a bit later. There we are. 6. Using MIDI note names: As well as using the midi numbers here, we could also use the midi note names. So we can have exactly the same thing here, but we can use the note names IEEE C4, E4, and G4. So let's, let's try that. So if I want to use a note name that I need to use a prefix it with a colon. So I simply hit here the colon C four. I can use a mix, so I don't have to choose one or the other. I could use C4 here and 6467. That'll work perfectly well, exactly as it was before. I sometimes prefer to use the note names when I know what they're going to be. But the note numbers can be really useful when we're doing more kind of algorithmic work later on. Now, don't worry about that for now it's a big word, but nothing to worry about. But you'll see that midi notes can be, the numbers can be useful later. Let's change this to a C4. Sorry, this should be an a4, G4. And again, this is gonna give us that the major or C major triad. But what if I want to use sharps and flats? While it's pretty easy to do. So if I want to use a flatness, flatten the, flatten the third here and this triad and make it into a minor chord, minor arpeggio. I use that just using the lowercase b. Let me also change that E into an E-flat. I can also use a, an S to denote a sharp. So if I wanted to say instead of E flat, I wanted to say D-sharp, same notes, but I could do that here, so I could just go a D. And we use the lowercase S for sharp on octave number four, where we are to change octaves. And if I want to go down an octave, I could, I could just change the optimal number here. And this will play an octave lower. Again. It really, as you can tell, it really, really doesn't matter what order I plane. So if I wanted to do an inversion, for example, maybe I play the G first. So let's move that up there. This time I'll need to put asleep in here. 2.5th. We can move this one from the end. And there we are. So have a play around in there and produce some little short pieces of music just using the midi note names, remembering that we use a lowercase b for a flat, a lowercase s for a sharp, or you can use the midi note numbers there. Have a play around, create yourself a little tune. I'd use the sleeps to provide the rest between notes that you want. 7. Code comments: So let's change this back. We'll put the sleep back here and play that G3 at the end. Loops. Again. Let's run that. Okay, so those are our C minor triad, C minor arpeggio. So we might want to just remember what we've called that. So let's go up here and we can use the hash command or the pound sign or the hash sign depending on whether which side of the Atlantic you're from. We can use the hash sign to say that this is gonna be a comment in our code and add a comment is just a piece of text just for us. So it's not executed by Sonic Pi at all. And we can type anything we wanted here. So we could say, this is a C minor arpeggio. As I say, that code's not going to be executed by Sonic Pi, but it's just notes that we can put in the code for ourselves. We refer to as a code comment. Again, if I, if I run this, it's completely ignored by the sonic pie, but allows us to put comments in. One of the thing that's commonly done by programmers is to use comments just to tell a sonic Pi to just ignore a piece of code for now. So if I wanted to experiment with this and say, okay, well what happens if I remove this sleep? Well rather than delete it and then if I don't like it, I had to type it back in later. I can just go and put a pound sign or hash sign at the beginning and run it again. And this time it's going to ignore that sleep. We can see that it plays a D-sharp and the G. At the same time. Again, if I don't like that, I just go ahead and remove that comment. I'm about to how we started. Now there is a shortcut key in Sonic Pi, a bit like the command R or control R to run the code, there was a shortcut key, if I want to comment something out. And this is a really good one to remember for live performances is you want to switch bits of code on and off. And I can press the Command and the forward slash key, and it will add this little symbol in the front. Now, it looks a little bit different, but it works exactly the same. Two hashes and a pipe side. This just put in a comment a little bit of the code. So wherever I am on a, on a, on a line of code, I can just press Command or Control and forward slash. It will comment out that line of code. And then when I run it on back to the to the court because the sleeps have been removed. If I want to remove that code comment again, I could just go back again anywhere on that line and press command and forward slash again, or Control and forward slash, and it will remove that code comment. And then we are back to our arpeggio. 9. Play options: So as well as using code to define the pitch of the note we want to play, we can also add a number of options. And you'll see these throughout Sonic Pi options which allow us to customize the sounds that are being produced. So we're going to start with two simple ones which we can add to the play commands. So let's, let's create this down. And let's just add a nice simple Play, 60. Okay, so that's going to play at the default volume for Sonic Pi. But part of music is the dynamics of the music and the dynamics of music involved the volume at which the notes are being played. So if we want to change out, then we can add an option to it. So for Sonic Pi, this is called the amplitude option. So let's just add this. So if I hit a comma and once I hit a comma after the sixties allows me to add a number of different options. The amplitude option or the volume option is simply called AMP. And you can see that here in the, in the code completion window. So Sonic Pi is, again try to help us out. So what's used? The amplitudes. So we'll say AMP and then we say colon. And now we're going to set the amplitude. The amplitude and Sonic Pi is defined by a number, so 0 is no volume at all. One is the normal default output volume, but we can go up from there too. So for example, if I set the opportunity to nought 0.5 and press play, that has just been output at half of the normal volume. Now it's very difficult to hear that difference here. So let's add a little bit more code to demonstrate that. So let's start off with a play at 60. This is going to be the default amplitude. Will sleep for two beats. And then we will play this one at half volume. And you should be able to hear the difference. Okay, So you can hear that second note was definitely quieter. Let's add another sleep. And again, we'll play at 60, but this time we will play it at twice the normal volume. We can set that as an opportunity to an area. So very simple to set. It's important to remember that the options that we set here only relate to the note that we're playing. So they only relate to this note. So if I just go and do another, another line here, I'll just out-of-plane play 60 with no options at all. So we can hear that line seven played just with the default amplitude of one, which is exactly the equivalent of typing that. But the, the, the settings that we make, the options that we put on here, the amplitude option in this case only relates to this note that's being played. It doesn't set the amplitude for all future nodes, for example. As well as amplitude we have pan. So this is the second simple option that we're going to look at now. And pan is simply setting the where the sound is going to appear within the stereo field. Are you from, from left to right, often called balance. So let's do this again, but let's, Let's just start here. So we can say again, a play 60 by default is going to send it right down the middle. So you're going to have an equal amount of this note in the left and right speaker or the left and right headphone. So if I do another sleep for two, this time, I'm going to use the pan option. So I press a comma and I'll say Pan colon. Now, pan in. Sonic Pi is set by a value between minus 11. So minus one will give us a pan all the way to the left. A one book gave us a pan all the way to the right. A 0 will palette straight down the middle, but I even an equal volume in the left and right speaker. And those values don't need to be minus one or one. They can be any value between minus 11. So if I want it halfway into the left speaker, then I can set the, the pan as minus 0.5, for example. Just to demonstrate this, let's pan to the left and right. So we're going to cancel the left first. We will go straight down the center, but pan to the left, will sleep again. And we will pan all the way to the right. We are fairly simple and you can actually, if you look at the scope and the top right-hand corner here, you'll see that. You'll be able to see that reflected in the scope even if you're not wearing headphones. So all the stuff above the line is the left speaker and the stuff below the line in the graph is the right speaker. I can combine these. So I could, I could then do another color and say, I want to set the amplitude as well. Cool. By typing apologies. So I can set the amplitude of this one to be half. Like I said, the amplitude of this one to be twice. Let's try that. We can hear, or perhaps you heard a little bit of distortion there. I certainly did. With this one. You just have to be a bit careful with the amplitude because as you go across, go up to higher volumes, you're gonna get some distortion in and cropping don't generally tend to go above 1.52. Only on rare occasions when you really want it for as part of the composition. Okay, so that's it for four options. In the next video, we're going to talk very quickly about beats per minute. 10. Setting the tempo: Okay, so here we have a bit of code which you should fully understand by now. Just read through it and just make sure that you understand it. But very quickly we're going to play a note at midi note 60. We're going asleep for one beat. Then we're going to play another note at 60. We're going asleep for one beat and then we're going to play a final note, note number 60. Now, as I mentioned briefly earlier, the when, when I set any kind of duration and he options relating to time within Sonic Pi, it is measured in beats. Now to keep this nice and simple. So asleep here, for example, is it's going to sleep for one beat in between these nodes. Now, to keep this nice and simple and to make the maths nice and easy. By default, anything that we play in Sonic Pi is set to 60 beats per minute. And this is done just to make the maths nice and easy so that I can look at that sleep one and I can think about that as being either a second or being one beat, because 60 beats per minute is the same thing. However, not a lot of music has produced a 60 beats per minute. So we need a way of being out of control what the beats per minute. And I'm gonna just gonna show you how to just very briefly. So all I need to do is go to the top of the program here. I'm just going to use this simple command. So I'm going to say use underscore BPM. Oh, put a hundred and ten, hundred, ten beats per minute. Now when I play it, going much faster, he's going 110 beats per minute. If I just comment this out using Command or Control and forward slash or by adding a pound sign or hash sign at the beginning. And run this again. There we are back to 60 beats a minute. If I remove that comment. There we are. So that's how we can set the beats per minute within, within our programs. 11. Synths: Okay, So this is great. We can actually produce a music using code and we can rest between notes or we could play all the notes together as a chord. You can set the amplitude, we can set the pan. But the sounds that is producing a not very interesting to your audience as soon can we be getting very bored or that beep sound coming out of Sonic Pi. Luckily, Sonic Pi has got over $0.40 built-in. There's a list on the screen now. We're going to look at some of them now. And there's some really great sense in here. So let's go back over to Sonic Pi. And we can see here that we've got just a C major triad. And to use one of the sensor is actually really, really simple. So what I'll do, I'll go up here. It's very similar to how we said use BPM before for use beats per minute. We can say use a synth. So we can say use underscore. Synth, hit Spacebar, we hit the colon, and then we type in the name of the synth we want. So just for this one, we're going to use tech underscore source. You can see the onscreen help is coming up to prompt us. And when I press Run now, you'll hear that it's going to play R, C major triad using the texts. Awesome. A much, much more interested in sound. Now, I could use any, any symptom here. So all I need to do is hit the codon and just type another one in. So for a three or three, for example, I could say TB three or three. And there's all sorts of great since in here. So for the 1800s we've got a profit. And as I say, there are a lot since in here now, as I mentioned earlier, the help section inside Sonic Pi is absolutely fantastic. Included in here for you. If you go down to the bottom left, you'll see this little tab called sense. Again, if you don't have the help section open right now, go up to the top and use this button to toggle it on or off. And then in here we've got the sense there is a complete list of all the sense in here. So let's have a look at blade. So I can just go down here. I just need to type the name. Heavier. We can just copy and paste this over here. So you can see there's a whole list of syncing here, which is exactly the same list as I just showed you on the previous slide. Go ahead. You've got your little bit of music that you've been playing with, with the play. Come up, go ahead and have a play around with the sense and see what interesting sounds that are in there. 12. Applying synth filters: Okay, So one of the things that we think about when we think about, since we think about filters. And there are filters built into the sense in Sonic Pi. So one of the common things to do with a synth filter do with the cut-off. And we set these in using the options in the same way that we set amplitude and pan earlier. So let's start from a clean slate here. And so we're going to use the tech sources. So use underscores synth, codon, tech source. And then we're going to play, I'm playing an E three. So an E on the third octave. That sounds like this. If I were to set the cutoff of the filter, then I simply put a comma, I taught cutoff a colon, and then I'll set the cutoff at 70. And this is what that sounds like. Okay, so this is setting the cost off on the filter. You can hear that That's really adjusting the way that note sounds. So let's, let's add another, another E3 here so you can difference of put asleep. This is going to play the E3 without the cutoff of the filter cutoff being set. And the, and then the E3 with a cutoff. There we are. And again, over on the right-hand side, you can see in the log window exactly what's, what's happened here. We've played tech soars with the note at 52, which is an E3. Then we have played the texts orders with a note at 52, with a cut off at 70. And you can see that the time we pay that, this time part of the logs here, this is when the sound was played or when the action occurred in relation to when we press the Run button, the start of the piece. So straightaway at time 0 is 0. We played 52, and then two seconds later, we played the textiles again, again at 50 to 70. So that this part of the law can also be really useful for to see what happened in what order and when it happened. And again, it's really simple to work that out now with a simple piece of code that has a code gets more complex, you'll come to find the log more and more useful. We've been talking about synthesisers and the concepts of synthesizers like filters, and they're applying filters. And in a second we're going to look at resonance. If these concepts are new to you, I definitely recommend you check out my other course that complete beginners guide to synthesis and sound design. That course will take you through these concepts and much, much more detail. But for now, let's move on and have a look at the resonance. Very briefly. A resonance is just giving a bit of a peek in the filter just before the cutoff. We set the residents just using another option. Like I said, we can just add our options by, by putting a comma after the current option. So let's, let's do the same again so we can make sure that we can hear the differences. So let's do an E3. We'll set the cutoff the same. So to set the residents, I just add another option. So I hit comma. And I'm going to set the resonance by using the option raise, RES, hit the colon. Now resonances are set as a value between 01. You can't set a one. So one. The residents could be anything below one and above 0. So in this instance, the texts or sent, if I look down here in the help section, I look at sensor like a tech source and I click on resonance. I can see that by default the resonance is set to 0.7 for this synthesizer, that it may be different for different synthesizers. Let's just change that. Let's set that to null 0.9 for this. And you'll hear a subtle difference in the filter for this synthesizer. There we are. So that's how to set the filter cutoff and resonance is for synthesizers have a play around. These effects will be drastically different for the different types and sizes. So change this up here, play, play with different types of synthesizers and change these cut-off and resonance values here. And to really experiment with these features. In the next section, then we're gonna look at another popular part of synthesis, and that is envelopes. 13. Envelopes: Okay, Before we dive into some code, let's have a look at what envelopes are. Now, we'll run through a brief introduction here, but again, if you want more information, then please do look at my complete beginners guide to synthesis and sound design course. An envelope is really just a way of describing the amplitude or the volume of a sound over time. Just to find it. Where to find it on this graph here. So on this graph we have the y-axis, which is amplitude or volume. On the x-axis is then the time. So the first part of the envelope is the a for attack. And often you'll refer, you're here the term ADSR. Now this is just another way of naming and envelope. So if people are talking about ADSR, they're talking about an envelope. There are various different types of envelope, but ADSR is the most common. So a stands for the attack, and this is just simply the amount of time it takes to get from 0 amplitude to the maximum amplitude. When we, when we trigger a note. D then stands for the decay. And this how long it takes to get from the maximum amplitude at the end of the attack phase to the level at which we want to sustain the note which is the S and the S. The sustain is set in terms of volume or amplitude rather than in terms of time. The release is how long it takes to get from that sustain level down, back down to 0 amplitude at the end of the note, one note is released. So a DNR are all determined by a time period. And S, the sustain is determined in as an amplitude or is declared as an amplitude or a volume rather than, rather than a time period in Sonic Pi. Then we also have three other elements, which are the attack level, the decay level, and the sustain level, and these are also volumes. So let's go over to the code and see how we can use this to affect our sound. Okay, so here we are back over and Sonic Pi. Let's have a look at ADSR envelopes and how we can configure those within Sonic Pi. So let's start off with a simple play command and we'll just play a C4. Okay, so to set the envelope or the configure the envelope, set the parameters of the envelope. We just add options on the same as we did with Pam, level cutoffs, resonances, et cetera. So exactly the same. Again, it's nice and simple. It's really been designed very well to be very standard. So you can kind of hacky way round and follow the same pattern for four different options. So again, we hit the comma. In here. We're going to set different parts of the envelopes. We're starting with the release. So I think it's the easiest to here. So it will set the release, release codon. That's a force that's going to be two for four beats. Again, because we're on a BPM of 60 by default, this means that we're going to release over four seconds. So let's play that. So you can hear that it took four seconds to get from the sustained amplitude down to an amplitude of 0. I say that again. We can set the parameters of the ADSR envelope in very much the same way. So we might want to set a attack. So we can just go in here. We can add another comma. And we'll say this time we're going to set the attack. I will set the attack to 2.5th on our ADSR envelope. Then it took 2.5th to get from 0 amplitude up to maximum amplitude. And then it releases over four seconds or four beats. But as I said, we've got the attack decay, sustain, and release that we can all set. We can also set the attack level, the decay level, and the sustain level. And just to remind you that the attack is the time taken to get from 0 amplitude to the attack level. The decay is the time to move from the attack level to the decay level. The sustain is the time taken to move from the decay level to sustain level. And the releases the time to move from the sustain level to 0. So let's, let's, let's configure our notes them with all of those options. So let's stick with the attack of 0.5, but we're going to say our attack level is going to be one. So what will set that? So we can see again, I could just use the arrow keys to move up and down in this code completion window here. And then when I got the one, I want to just hit Enter and it will put it in for me. We'll set the attack level to one. We'll set that to k. So we're going to set decay to one as well. We'll set the the decay level. We'll set that to be not 0.7. We will set the sustainable. I will set that as no 0.4. We'll set the sustained to be two. This is actually brought me to a good point. So it really doesn't matter in Sonic Pi where it kind of ignores carriage return. So if I get to a line here, and because my font is very big, if it gets her slide here, that's kind of scoring off the screen. I can scroll left and right, but actually, it's probably easier just to hit Return. And you'll see it there, put it onto a new line. That's perfectly fine. If you just want to organize your code in that way, it will ignore carriage returns or the Enter key. So back here I've got a missing comma here for the sustain. So let's run that. So we've taken a sound which just to demonstrate, I'll add another play the same sound here so as to a C4 and sleep for two. So this is going to play the default sound is going to sleep for two beats. And then it's going to play this one with the envelope that we've set up in the way we want. So you can really hear the difference. And again, I can combine this with other things that we've learned within Sonic Pi. So I'll use a synthesizer for this. So let's, let's use, Let's use the synth profits. So there we are. That's, that's envelopes within Sonic Pi, nice and easy to do. Again, we're just adding it as, as additional options after our play command. The thing to do now is to experiment with different sense but also with different envelopes and see what interesting sound gene come up. Try and go for some percussive sounds with a very short attack and a shortish release, which will give you a much more percussive sounds. I would try some really pad like sounds by setting the attack and release to be very long. So have a play around with the parameters inside there. Don't worry, you can't break anything. And I should just show you through the error commands. So if for example, I set the lesson it something that's going to give me a sure-fire error. So if I take the attack level two minus one, so it attempted to play, but he got his gotten as far as the attack level and then we hit an error. So I can see in here then the value of the option attack level must be 0 or greater and it got a minus one. So this is really, really helpful, Eric commands inside, inside Sonic Pi. If you do get these kind of pink lines come up or these error messages shown, you can dig down into much more detail in here. But in general, if you read these, these kind of big bold error messages that come up, That's going to give you a really good indication as to where exactly in your code the error has occurred. And as I said before, is a really nice, safe environment. You can't do any harm to your computer or to any other running programs. Really do. Feel free to experiment inside Sonic Pi. Try stuff out. If it doesn't work, it's gonna give you a nice readable error message which will point you in the right direction. 14. Playing samples: Okay, so we've looked at the default play command, which plays that beep noise. We've looked at being able to change that sound both with the ability to use a different built in synthesisers within Sonic Pi and being able to change various options like the volume or the amplitude, the pan. Apply filters and cut with cutoffs and resonances and being able to adjust the envelopes. So hopefully you've had a chance to have a really good play with those and really understand how that's all working. But there is another way to play sound within Sonic Pi, and that is through the use of samples. Now there are a number of built-in samples within Sonic Pi, and you can see all those down in the help section here. If you click on this tab for samples, it'll give you a list of sample categories. And then you can jump into these and play the different samples. Now, as I said, the help section within Sonic Pi is absolutely fantastic. If you go through here, you'll see all the different samples that you can use. And actually if I just go and choose one here, if you choose this little arrow next to it, That's actually a play button. And so you can audition the samples within the health section. So if I play next to this skinny boom, for example, hit this Play button. There are lots and lots of other high-quality samples built into, into Sonic Pi. Now to use them, I just use the sample keywords, so I simply type the word sample. Then I hit the colon and the name of the sample that I want to use. So there's a one which is guitar, which is an E minor ninth. So if that's the sample, I'm going to use that and like that press Run. Again, I can apply the same options as I have done to the plague of n. So if I go to the end here and I can set the amplitude, for example, that's an 0.5 and we'll panel all the way to the left, which again is a minus one pan. And play that. So there we've heard a half volume sample pan all the way over to the left ear. There are lots and lots of samples built in and I would encourage you to have a dig through here. So if we go down and have a look at some of these sounds when looping, for example, we can see the Amen break here. So if I, if I auditioned a sample, if I want to play that within or use that within my code, I can either go and type it in or I can actually just go and copy that in with Command C, Control C. Or I can right-click and copy. And I can just take that and paste it up here. So that's going to play a sample at the speed that it was recorded that. But I can actually change the rate of samples again just with another option. I said that option using again a comma at the end, I can set the rate, which is the speed of the sample. Now, by default, all the samples played with a rate of one and that is the rate or the speed at which they were recorded. But I can set that to play at half the speed. So 0.5. I could get it to play at twice the speed or rate of two. I could play at a 1.5. Or interests me if I take a negative number, if I play a rate of minus one, this is what happens. I play in the sample in reverse. Let's set that back to a rate of one. If you're going to play stuff at a rate of one, you can just remove this option. I'll leave it there for now. But everything about everything by T fault rather plays at a rate of one. But I can also use external sample. So there are lots and lots and lots of samples built into Sonic Pi. I definitely spent five minutes now just having a play around inside. Lots of really, really useful sound. So I don't know. We've got the, the lunar landing, an ambient sound. There were lots of kind of built-in drum samples. For example. There are some more drum samples and here they're a bass sounds. Glitchy sounds, snare drums. There are, again lots of loops and a bunch of vinyl sounds for adding a lo-fi filter music. There's a whole bunch in there, so I definitely encourage you just to spend five minutes now pause this video and have a dig through the samples and audition a few and play around with them and play around with the rate and see what they sound like, reversed or sped up or slowed down. Now there the built-in samples, but actually we can use samples that we've recorded ourselves from, just load, load them in from our hard drive. So let's go here. And the way we do that, we just specify a path. So this will be slightly different on Windows on a Mac, I'm on a Mac. So to do it, then, all I need to do is press sample. And then inside quotes, I just need to tell Sonic Pi where the sample is. Now, if you're on Windows, is going to be probably see colon forward slash something or C colon backslash. And then the path of wherever your sample is. I'm on a Mac. So my sample is on my desktop. So I'm going to go to Users, Steve, onto my desktop. And then I have a sample called beat one. And there we are. So that's all I need to do to tell it to play a sample, that's to load a sample. And from my hard-drive, again, I can change the rate of a sample I've loaded in. Like so. This is obviously going to take a long time to play. So this is a good example of using the Stop button or pressing Command or Control S on your keyboard. There we are. So we can start, stop it halfway through a run. And again, I can play that in reverse stock that I can play it at twice speed in reverse. Okay, so there's another option for playing samples as well. We can just point to a folder and we can use an index to, to, to say which one to play. So this is really useful if you've got a sample library or a folder on your hard drive, this has got a bunch of samples in it. And so we just, we just tell it which sample we want to play with in a folder. So we can just remove this here. We can say, okay, play the first sample. Now, here's something to point out to you. So when we are programming, it's very, very common. In fact, almost universal within programming languages that the first item in the collection is the 0th item. So counting within a computer always, always starts at 0, certainly within Ruby and Sonic Pi. As I said before, Sonic Pi is based on Ruby. So when I say I want to use sample 0 within this folder, this means play me the first sample within this folder. Now I've only got one sample in this folder on my desktop, so it's going to play the same ones we had before. Now, you will see later on that this can be really useful because we can use codeine to determine which sample we want to play without having to know the name of every single sample. We can just say Play me sample five, play me sample three, sample ten, et cetera. So that's just a different way to access samples. But again, if I just wanted to access a specific sample, I just type the full path and the name to it after the sample keyboard. Now, envelopes for samples work in exactly the same way as they do for sense. So, for example, we could set the attack of this sample. We can say, I want this, the attack for the sample to take four weeks. Let's play that. So we can see from there that it took four beats to get from 0 amplitude once we trigger the sample up to the maximum amplitude. Now, sustain for samples is slightly different, so the sustain is automatically set to the length of the sample. So remember the sustain is the only part of the envelope that we did that we defined in terms of time, the rest of the defined in terms of amplitude. But the sustain is automatically set to the length of the sample. Or we can set it as usual. So I can set the sustained to be Let's say two lists. Let's remove this attack just to make sure it's very clear. There we are. So because I told us to sustain for two beats, it played that sample for two beats. So I can also set the start and finish point to the sample. And I tell it how far into the sample I want to go. This is a value between 01. So it's kinda, if you'd like, percentage through the, through the sample that I want to start and finish. So I could say, let's start at nought 0.2 of the way through the sample. Let's finish at no point to six. So that's played out here that we start into the sample and we finished before the end. There we are. So that's sampling or playing of samples within Sonic Pi. In the next section, we're going to have a look at program flow and start to build up more complex programs, to start to produce more complex and interest in music. 15. Program flow: So what do we mean by program flow? Well, program flow is just a way of determining in which order the instructions within our program are executed. And it's really down to three basic concepts. That is sequence, selection and iteration. Sequence is just the execution of instructions in order. And that's what we've been seeing so far. So for instance, we played a note, we slept and we place them another nodes. Then we slapped ME, played another note. This is just the execution of those instructions from the top of our code file to the bottom in the order that we typed them in. Selection is just a way of being able to determine which action to take within our code based on something else. So we might say that if this has happened, then do this otherwise do something else and that will become much clearer and I explain conditionals later on. The third part iteration is just being able to do the same thing over and over and over again a number of times. Now this may go on an infinite number of times or a predetermined number of times. But say for example, we had a, the C major triad that we started with right at the beginning of the course. Now, we could play that C major triad 16 times by typing that same code in 16 times, asleep between each. So we might do a C major triad sleep for a beat. Another C major triad sleep for a beat. But every time we do that, well, that's four commands, isn't it? So there's three play commands to get our three note snarl, triad and asleep. If we want to do that, ten times x for example, let's say, for example, keep them nice and simple. If we wanted to. We wanted to play that, that C major triad ten times, we'd have to repeat those same four lines, the three plays and asleep ten times within our code. In order to play that same code, ten times iteration, it would be a great way. I've been able to just say, okay, well here's those four lines of code. Just do those ten times. And that's what we're going to look at next. 16. Loops: Okay, so if we think right back to the beginning of the course and we had a small piece of code which played us a C major triad and it looked like this. So as I said before, if we wanted to play the C major triad ten times, you might want to do something like this. So let's sleep for one beat and then we can type our C major triad again. And then we can do that another eight times. So we might get smarter and we might say, or we can copy and paste, right? So we can a copy that Motors keep patient that as three times four times 5678910. So there we have our ten major or tenancy major triads in a row. And this is using the sequence part of the sequence selection iteration program flow that we learned about in the previous lesson. So it's just executing every single instruction in order. I got to use the stop button. Or you can use Command S or Control S to stop it through the program flow. We don't need to hear all that. Now this works perfectly fine. It's absolutely fine. We'll operate and it's perfectly fine to do this, except that you can see that to produce music of any kind of length, you're going to end up with a, an awfully long program and an awful lot of repeated code that's very, very hard to read. So the way around this is to remove this. The way around this is to use a construct called on loop. And this is where we move into the iteration parts of the program flow. So in Sonic Pi, the keyword for a loop, I used to do things round and round and round again. Lucas, actually a really useful way to use because we use loops in music anyway to mean something that just plays, well, that can be played round and round and round again. So we can say, okay, well, so let's look this one. I'm going to type this in and I'm going to explain it. So what we said here is we use the keyword loop and then we say do, is loop, do. Then everything before the end. We're going to loop around and round and round and round again. This will just keep going forever. So I'm going to stop it. Are the reasons can keep going forever. Is it, it's gonna, it's gonna say loop do. And it's going to play these, this triad, going to sleep for 1 second or one beat. And then it's going to hit the end and it will go back round to the loop, do and do it again, play the triathlete for a second, hit the end, go back up to the loop, do, and then just keep going forever and ever and ever and ever. However, what we can do is a different type of loop. We can say to Sonic Pi that we want to play something a certain number of times. The way we do this is very simple. So we replaced the loop keyword with the number of times that we want to repeat. So we're going to do this three times so we can see it through to the n. So we just say the number of times. So three dot times, do, so, do this three times. And there we are. So then, then our program flow is going to revert back to the sequence part. So we could say play this three times. And then we'll just make another chord. So let's do a, a G major. So we're gonna go, we'll say colon, G4, a before. And a. The five should give us a, a G major triad. And there we are. So we can see that that would have taken an enormous amount of code to do. At least we can work it out, right? So we've got these four that would have been repeated three times. So that's 12. And then another four repeated three times. So that would've been 24 lines of code. And we reduce that down to this. And we can see that this is much, much easier to read, particularly if I use a code comments. So I can say, oh, excuse me. So I can put a comment in here to say, to say this is a C major and then this is a G-major Nebula. We can see we've got a much, much more readable piece of code. This number of times doesn't have to be three. It could be anything you want. It could be 60 and it can be 20, could be a 100, whatever, whatever you want it to be. The one important thing to remember about loops is that every loop must contain asleep. And in fact, if we just remove this for now, if I remove this sleep, then what happens is the computer so fast, it loops through three times. You heard that was very distorted. But it actually done is it played that triad three times all at the same time. And that's why we must put asleep into every loop because the computer so, so fast that it will loop through those three times in a fraction of a second. We must remember to put the sleep command into, into every loop. 17. Nested loops: Now we can also nest loops, uneven loops of different kinds inside of each other. So we know we've got the loop do and we've got the three dot times du or the 16 times do we can nested inside each other. And I'll show you a bit of an example here so we can say loop, do we know that we're going to need an end? Now, you'll notice that when you run things, it formats the code and puts the indentations in to make it easier to read. Another way of doing that without having to wait for it to run as to press Command or Control M, four M for mother. And that will just format the code nicely for you. So I can say here, sample little play the bass drum, sample, BDI, underscore house. Again, Control, Enter. Control, Control or Command M will format that for you. So that's playing outside one loop. If I play that now, it's going to play it once. And the reason that it's failed as there's no sleep inside that loop. So during the plague of audits, it's fine. It's just going to play them all at once. But actually, as I said before, Sonic Pi is very much geared towards learning and to save you from doing something that could potentially use up a lot of processor and memory on your computer actually has given us an error here to say we didn't sleep, because playing samples is much, much more intensive on your system resources than just using, just using the play command. In automate this to work, we want to put asleep. And here, this is just going to loop forever. Play in that sample with a snip of quarter of a beat between a stop that less and less. And lets nest another loop inside this. Inside this, we can say every time we go around that loop, we're going to play that sample once. And then we're going to play for hi-hat. So for every kick drum, every bass drum that we play with this BD, how sample we want for high hats, quite a common for to the floor beat. So let's say for dot times do. How will play a hi-hat sample here, omega one n that loop. Let's press Command M to format that. And then inside this loop, we're going to play a hi-hat sample. So we've got one built into, built into Sonic Pi. So we're going to say drum symbol close. That's the one we want. Then we're going to sleep for nought, 0.25 of beats. So four, we're going to end up with four closed hi-hat per beat and then one kick drum. So let's sleep. Sleep for quarter of beats. Before we play it. Let's have a read through this to make sure that we fully understand. So we're going to loop forever on this outer loop. And within that outer loop, we're first going to play the BD house sample, which is a bass drum kit sample. And then after that sample is played, although as I said, it computes so fast, it will be the same time we're going to play for closed hi-hat with a quarter of a beat, sleep between each one. Then once he's played the four hi-hats, we're going to loop back around to the top. Play the Keq for high hats, play the kick for high hats. So we play the kick and this loop. And then we play the four hi-hats. We can see that these are what is referred to as nested loops. So let's play there. We are. There's our first basic beats within Sonic Pi. 18. To infinity, but not beyond!: One last thing to say about loops is just to warn you a little bit about infinite loop. So let's, let's add another, another sample command here. And let's just say we're going to play the, the skinny. Boom. So let's listen to what that sounds like. I'm going to stop it there, but it would have gone on forever. Okay, so the, the, this sample here on line nine never gets played because this loop is just going round and round and round again. So we never kicked back to the sequence part of the program flow. So we never actually get to line nine at all because we're going from line one to line seven endlessly. So I would warn you against using loop do and only use loop do if you really, really mean it. So I would say to set the number of times whenever you can. So we might say for dot times. So it's going to play this outer loop four times, the inner loop four times within each one of those. So we're going to play for kick drums, and they're gonna play 16 hi-hats before we play this final sample. So this will now actually get to line nine. Okay? So to practice this and what I'd like you to do is to take the code that you can see on the screen. Now, it's hard to get that working and then play around with the beats. So everything there is something that you understand well. So I guess the next thing to do would be to try and to add a snare sound into that beat. 19. Enhancing your beat: Okay, So perhaps you've ended up with something that looks something similar to what we've got here. Let's play this. And we can see that we're looping around four times. You're playing the kick drum. We play two hi-hats, limit play in this snare sample, another two hi-hats, and then we loop back around to the kick drum again. Don't worry if yours doesn't look exactly like this and it probably doesn't look exactly like this. As long as you kind of understand how the loops and how the program flow works with the sequence of the iterations. And you've managed to get out a pleasing beat. It's definitely worthwhile spending a little bit of time with this and thinking about our b2 you want to produce in your head and then seeing if you can get that down expressed as code. 20. Randomisation: Okay, So I mentioned earlier the use of midi note numbers rather than, than the mini number. So using 60 instead of C4, for example, can actually be, although counter-intuitive, really useful at times. I'm one of those times is when we're using a random number generator. Now, randomization can be really useful for kind of generative music or for having the computer generate or create some music for you based on random numbers that you just wouldn't come up with yourself. Whether that's actually for part of your composition written into code, or whether it's a kind of inspiration, just play with some random values and give me some inspiration towards a melody or a baseline, or whatever it is I'm looking for. Generating random numbers in Sonic Pi is really, really simple. And because we can play a note number rather than a name, it means that we can generate a random number and then play that note. So the way we do that is with the rand command. Let's see how that works. So we know the, we know the play. Come on already. We got play 60 as we've used many times. Well, that's just going to place a note with the note value of 60. But we can say, Play me a note with a random value. So I can use the rand command and I can say in here inside brackets. So I can say, Play me a random note between number 50, number 100. Okay? So if I look over in the log here, I can see this plate me a note at 87.5031. If you type that into your code window and run that code and look at your log. And I can also guarantee that you will generate a random number or random node, which will be 87.5031. Now, this may seem odd. This may seem odd because it's not truly random, is it? If you're able to put in the same code as me and on your computer a different time and place, generate the same random number, same random notes. It's not truly random now this is done for a reason. The reason being that you want to be able to share this code on all, play this code on your computer a later date, and guarantee for it to be the same so that every performance is the same. So have a play with this, generates some different random notes. So again, to change this, we might say, okay, generate me a random number between 4080. There's a different random node. So in order to generate a different random note, what I would need to do is to set the random seed. Now, again, this is done on purpose. This is a deliberate design choice within Sonic Pi to ensure that if you come up with a piece of code that uses random notes that you really, really like the sound of. That it will be the same every time. So you can see it's a deliberate design choice. But to change the randomization, I just need to use a simple command which is used random seed, use underscore, random underscore C. And I can type in any number here. And it really, really doesn't matter. And you'll see, we can use this a little bit later and we'll change the random seed to generate different random patterns. But I could, for example, change in, use random seed here to 40. You'll notice that the last time I ran this, I generated note 70.0024. That's interesting in itself because the notes in Sonic Pi don't need to be whole numbers. So actually shows you that you could write programs in Sonic Pi to produce micro tonal compositions. But we can set this random seed. Like I said, it doesn't really matter what the number is. 99 is fine. When I run this now. Now I've got a note which is 68.63. And again, if you use that random seed and this round command exactly like this, on your computer, with the random seed of 99, your jet, you will also generate that same note. And again, it's so that you can save this composition and you know that it's going to play in exactly the same way every time. So let's take a little bit further and see how we can use this to produce melody. 21. Generating melodies with randomisation: So let's just get rid of this for now. We'll say, okay, Play me a random note between between 5100. But we'll, we'll wrap this in a loop. So as we saw before, but just do loop, do an end. We need to remember to put asleep. And so let's put asleep of one in here and press Run. And if we can call that a melody, then you will have produced the same melody as I did if you run that code on your computer. We could also randomize the sleep. Because sleep is just a number between, between 0 and whatever we want it to be. Let's say rand. Generate me asleep between nought 0.25. So quarter a beat, 1.5 beats. And let's run that. Okay, so there we can see we've, we've randomized the, not only the note but the time between nodes. So we could swap the play command for a sample. So let's look at that so we can play sample. Let's do B glass rub. So here we were playing the same sample, but we're randomizing the time between samples. But don't forget, we can use the rate option of a sample to speed up or slow it down. So we can do exactly the same with the random value there. So we can set the rate to be a random value between 0.52, for example. So that'd be honest. So we can use the randomization functions to create random values to go in any option which takes a number, which is why it's so useful that Sonic Pi has been designed in such a way that we set the options with numbers, and therefore we can use random values in the vast majority of them. So have a play around with different, you might want to look at the envelopes, filter cutoffs, resonances, patterns, and amplitudes. Just insert some random values using the rand function. And you'll start to create truly generated music, which as I say, you might, either, you might either want to use in your composition directly or use them as I do. Occasionally is just to play some random values, play around with different options and different random values in each one to provide some inspiration for a composition. 22. Other random functions: Awesome. Other randomization functions within Sonic Pi, which can be used to produce slightly different values. So let's start off with a loop. This loop will just play a C4. We're going to set the amplitude simply to rand. And then we will sleep for half a beat, the rand function and then Sonic Pi will always produce a value between 01. So let's play that. This is just a shorthand way of writing this which would be exactly the same. We can also tell it to return an integer. So if we wanted to have exact midi notes, we could say round underscore i, between 5000. You'll notice that when we play this, if I look in the log, then we only have whole notes here. So a whole integer values. So nothing after the, after the decimal point. So we know that there's something on that, the midi scale. So again, have a play around with the random function. We looked at our round and round. Remember that aren't I, it will give us an integer. Rand will give us a floating point number, or a number, perhaps with something after the decimal place and round, which will give us a number between 01. Have a play around with those, put them into different parameters, play some different nodes, sleeps in different lengths of time. Just play with different amplitudes and envelope parameters and really get used to the effect that randomization can have. On your note, the interesting kind of generative possibilities that you can have within your code. Once you're done playing with the randomization functions, we'll move on to the next section, which is going to cover the final part of program flow, which is selection. 23. Selection: To work with the final parts of program flow, which is selection, we're going to need to understand a couple of programming concepts. Let's have a look at them in the next couple of slides. So the first thing we're going to look at is a thing called comparison operators. Comparison operators just allow us to compare one thing against another. So when we're looking at selection, we need to be able to determine if if one thing is true or another is false. So for example, we want to be able to execute a certain part of code if something is true or a different part of the code if that comparison is false. So in order to, in order to determine that we have a number of comparison operators. You can see them on the screen here. There's only six. I'll explain each of these in turn, but they're fairly simple concept. So the first comparison operators is a double equals sign. And this is equal to, now, it's a common error and I still do it myself. I've been doing this for a programming for over 20 years and I still do this myself. So don't worry, but when we are doing a comparison, we want to see if a compare one thing to another. We need to use the double equals sign. And that is because we use the single equals sign for something else. So although normally in your mathematics we would use a single equal sign for comparison in programming, we use the double equals. And I, when I type this in my head, I say equal to. So there's two words, two equals equal to two equals. So if we want to see if one thing is equal to another, double equals sign. If he wants to say that, if the thing is equal, the two sides of that equation, if you like, are true or are equal, then it will be true and we can execute code based on that. The next comparison operator then is the not equal to. So if this side is not equal to this side, or if a less left side is not equal to the right side, then it will return true. If the two sides are equal, then it will return false. That we then have the greater than and less than operators. So if the left side, left side is greater than the right side, it returns true. Or if the, if the left side is less than the right-hand side, then it returns true. We then have a final two operators which are very similar, but they include the middle bit is less than or greater than or equal to or less than or equal to. So we could say if a certain value is less than or equal to, or greater than or equal to the other value, then return true. Otherwise it returns false. This, I know this is if you've not done any programming before, this is a, can be a little bit odd. It will become much, much clearer when we look at some code examples and we'll do plenty. So I'm probably a good idea to note these down. So we've got the equal to, not equal to, greater than, less than, greater than or equal to and less than or equal to. There may be an occasion where we want to chain these together. So we want to say, if this is equal, if a is equal to b and c is greater than d, for example, or if a is equal to b or c is greater than t. Again, this is going to be much, much easier to explain and to understand once we see some code. But just, just to say that we also have these combining operators or logical operators. So this is how we combine the comparisons together. Again, a double ampersand or a double and signed means, and a double pipe means all. And you'll find the pipe sign on a Mac at least just above shift and backslash. But these will become much clearer. We'll jump over into, into Sonic Pi now, we'll write some code using these kinds of operators and you'll see how they work much better. Okay, So the way we do selection inside Sonic Pi is with the use of the if keyword. It's very simple to understand. So let's just dive in and write some code and you'll see how all these operators work. So let's start off with a simple example. So we can say, if one is equal to one, then play. I didn't know the Amby glass rubber. As with all the code blocks within side Sonic Pi, we need to put an N on the thing here. So this is saying if one is equal to one, which is always true, one is always equal to one, then play this sample. So we should hear that sample play. Okay? And we can prove this worked by. We can say if one is equal to two, then this sample should not play. Okay? And we can see over in the log, that's our run started and completed. But the sampled in play, because one is not equal to two. So we can look at some of the other operators here. So we can say if one is not equal to two, then what would we expect to happen here? Yeah, we'd expect the sample to play because one is not equal to two. And there we go. So the other operators we might use are if one is greater than 21, is not greater than two. So we won't expect the sample to play him. If we look over in the log, you see the runs starts and completes and the sample doesn't play. But if we say if one is less than two, then we can press, run. The sample will play. You can see that it's a very simple concept and it's just, it really is that selection. So if this thing evaluates as true is that if this expression and we call this an expression here, this expression evaluates to true, then carry out the code with inside it. 24. if ... else: So let's have a look at what we might do otherwise. So we can have two execution paths. So we can say, if this is true, do this, otherwise, do this. So let's leave that as it is, and we can see the keyword for the second path, the fall. If the first expression evaluates to false, we can create a second path and we use the keyword else for that. And I'll just play us a different sample here. So something that's very different. So let's, let's pick, let's pick an age, a weight based on a weight-based room. So we can say, if the first expression evaluates to true, play this sample, let's make this nice and simple again. So if if one equals one, so if one, if one equals one evaluates to true, which it will play the ambiguous Rob else play the kick drum. So let's run that. And we would expect to hear the glass rod. So for this second part of the code to execute, this expression after the f would need to evaluate to false. So we can do that simply by saying if one equals two. Let's run that. And we should hear the kick drum play because this will, this will be false or a loop immediately jumped down to the else. Ignore this line here, jumped down to the else and play what's in the else block. We can hear the kick drum play. Okay, so what else can we do with that? Because this is, seems a little bit simple. Well, we could use some random values. So let's, let's change this to something, make something a little bit more easily here. So let's just get a hard base drum. And let's change this one to a. Let's see, a open hi-hat. So there's the bass drum because we one doesn't equal to two and we executed what was in the else. If we set this to true, There we are. There's our open hi-hat, so we've got two sounds. It nice and easy to hear. Very clearly different so we'll be able to fully understand what's going on. So this expression here is rather simplistic. Amino always execute to true. But some, perhaps we could do something else to make this a bit more interesting. So while we know we've got the randomization functions we looked at in the previous lesson. So perhaps it might be interesting to you some of those. So let's say we've got the rand function which returns a random value between 01. So we could use that. So we can say if r1 is greater than naught 0.5, this will produce a random value between naught and one. If that, if that value is greater than naught 0.5, then we'll play the open hi-hat. Open symbol. Otherwise, else will play the bass drum. So let's play that. Okay, so in this case, the random value must have been greater than naught 0.5. And so we played this here. We can put as many lines of code as we want to within these blocks. So we could have, we could play multiple samples, we can play multiple notes, whatever we wanted to do within the if block and within the else block. 25. Combining comparisons: Okay, so how do we go about comparing? So we looked at the logical comparison operators, But then we said we could combine, rather, we could combine those logical operators. We might want to say if this is true and this is true or this is true or this is true, let's have a look at that. So let's go back to our simple example. So if one is equal to one, if one is equal to one play, the open hi-hat is equal to one. So the open hi-hat plays. We can combine that with another one. So this isn't an, so we can use the double ampersand and we can say if one is equal to 12, is equal to two, then play the open hi-hat. But this will only play the open hi-hat. This piece of code inside the if block here will only be executed if both of these expressions are true. We can chain as many of these ones. You can have as many and's and or's as you want to have within your IF expression. So if I change either one of these, then to be false. So if two is, we can say if two is equal to three, well this is gonna be false. So therefore, one-on-one will always be true. This will, this will be false. So therefore, this, this, and this are not true because this is true, but this is not. So therefore the base rumble play. Now, what about if I change this to an OR? So this is the double pipe, remember? So this is basically saying if one is equal to one or two is equal to three, then play, then play the symbol. Otherwise play the bass drum. Well, one is equal to one. So it doesn't even need to go, it doesn't even actually evaluate this bit. It just says y is equal to one. This is an or. So. It doesn't really matter about what's here. This is irrelevant because only one of these things needs to be true in order to play this symbol. And again, if I change to two is equal to two. If this is true or this is true, play the symbol, otherwise play the bass drum. And they're both, they're both true. So that's completely fine. What happens if I change? One is equal to 22 is equal to three. In this case, we'd expect the bass drum into play because neither this nor this were true in this case. Okay, so that's a real quick look at how we do selection with inside Sonic Pi. 26. The one_in randomisation function: Let's combine this with some of the randomization functions perhaps to make something a little bit more interesting. So let's perhaps do this so we could do a loop. We'll just run it forever. But again, just to remind you, it really will run forever. So be cautious about using them in your compositions. And we'll go back to our random function. So if rand is greater than 0.5, so the, again, the rand function is going to give us a value between naught and one. If it's greater than naught, 0.5, play the symbol, otherwise play the bass Trump. Let's play that. Here you can see an error. My mistake. I didn't put asleep inside the loop and that's exactly what it's telling you said loop did not sleep or sink. So let's put asleep in there and run again. Okay? So there is another, another randomization function which we haven't seen yet but, but could be useful in this kind of situation. And that is the one in randomization function. Let me show you that. So we say if one underscore in, let's put a two here. So basically what one does is it returns a true with a probability that you put inside these brackets here. So one in two times, it will return true in a purely random in a random fashion. If I was to put a tenant here one in ten times, this will return true. If I put a one in two, we would expect an even distribution between the symbols and the bass drum. So let's listen to that. Okay, So they're playing about the same amount now, obviously in a random pattern, but, but about the same number of symbols as bass drums. And actually, if we went over to the login and scroll through the log and counted them all up. We can see the bass drum playing and we can play the symbols played. If we went through and counted those, we'd end up with about the same number. But if I change this to one in ten, I would expect hear the bass drum to play a lot more often than the simple, because one in ten times I would expect the symbol to play. And every other time else, I would expect the bass drum to play. So let's listen to that. Okay, so we can see here that using these IF operator, the selection withinside, Sonic Pi, combined with the randomization function, we can really start to quickly build some kind of generative functions of some generative music. Because of course, we could, we could play different chords, different notes, whatever we wanted to do, different samples within, within patterns such as this. 27. The simple if: There is a slightly simpler way of writing this code and that is like this. Let's get rid of this, get rid there. So we can say. So rather than having an if statement in which looks like this. So let's change this to one in four, so 14 times we expect the symbol to play. Otherwise we'll just asleep and go back around the loop. So this is done so often inside the code that we use to generate music, There's a bit of a shortcut to it. So it just means that we can remove this end here. And we can just cut that from there. We can put it on the end of here. So let me just read this through to you. So this is going to loop around, around, around forever. And it's going to say, play this sample drum symbol open if one in four. And it's just a bit of a shortcut, a bit of a quicker way of writing it. So we end up with the same result, but it's just makes the code a little easier to read perhaps. Oh, maybe we can just mess about here and just, let's just change our code. So let's play a, play a cow, a cow bell every one in six. So what this is gonna do is it's going to, let me just command M to do that. It's going to just make this a symbol close just to make it a little less ringy if that's a word. So we're going to loop around every corner of a beach. We're going to play a closed symbol. And then one in six times, we're going to play the cow bell. Okay, and that really is it for selection inside Sonic Pi. So have a play, but look at the air from the L and the shortened version of F that we got here have a play with the one in randomization function and the other randomization functions that we looked at in the previous lesson. And look at the conditional operators and combining those operators together just to look at different ways we can combine these and use them to make music which is unpredictable. 28. Variables: Okay, it's time to have a look at some variables. Now, a variable is just a fancy name for a label really. It's just a way of giving names to things that we can refer to them later. The easiest way to show you is just to write some code, but it really is just a way of giving something a name so that the computer can remember it. And when we asked for it later, it can give it back to us. That's all a variable is. Variables inside Sonic Pi, a very, very simple to use, but we use for them the equal sign. And this is why we had to use the double equals inside the comparison operators. This is what the equals is reserved for. So we say the name of the thing and then equals and then whatever value we want to store, the value can be anything. So we might say, for example, number equals 99. And then whatever we asked for number later, we can retrieve it using the word number. So let's, let's just make that really clear. So my number is 99, and if I say, if My number is greater than 98, just play 60. Otherwise aren't. In fact we just end. So we can say that we store the number or the value 99 inside a variable which we've called my number. And then later on we can use that. In our instance. We just can use a simple if statement to say if my number is greater than 98, play 60, so we would expect them to sound. There we go. So very, very simple to use and so Sonic Pi, but actually really useful because we can refer to this in many, many places. And when we want to change the value of it, we only got to go to one place to change it rather than change it all over our code. So let's look at a simple example. So one thing we might wanna do is named some of our samples so that we can refer to them later. And if we want to change that sample, then we can just change it in one place. This, let's see a good example. So let's create a variable called hi-hat. And inside that variable we're going to store the a sample name. So drum, symbol, close. So this is a closed hi-hat. Let's create another variable called snare. And we'll make that the, the sample or an underscore Zoom. And we'll create a variable called cake. And we will call that will store in that the name of the sample. Bdi underscore house. The use of variables become very clear now because if I create a loop, inside that loop, I will say, okay, for plenty of sample, play me the hi-hat. Then play me the sample kick. And then sleep for Quarter, repeat. Play me another harm, another hi-hat. And then sleep again. And play me another hi-hat. Sleep again. Sleep again. And then play me another hi-hat and sleep again. Let's play that. Okay, so maybe then on the third beat we want to bring in a snare as well. So let's play a snare and here, so let's play a snare or three, citizen to that. But what if I want to change the kick drum we're using? So if I want to change your kicked around, we're using while I've only got to go and change them on place. So it's not so bad. But want to change the high hat that we're using, I would have to go throughout my code and change if I'd use, if I've done it like this. For example, I'd have to go to every place in my code and change the hi-hat that I'm using. So let's just undo that. In our example. We can just change it in one place. So we will just change this to an open hi-hat. We can change it in one place. We don't need to change it anywhere else in our code. And there we are. So that's a good reason to use variables, but we use them quite a lot in the course from now on. But it's really just a matter of giving a name to something. You can store absolutely anything in a variable. One thing I will say about variables is always try to give them a meaningful name. Like if I had a call this a, B, and C, it would have been fine using it, using those now and I replaced it leaves a, B, and C would've been fine now, I ever would have remembered as I was writing the thing now. But actually if I was to pick up this piece of code in three months time and go and copy this piece of code out into somewhere else. You use them in a new song that I was writing. Or even just to open this and read this. And it would have been very, very difficult to understand, keeps a meaningful names and it will make your code so much easier to read. And we spend a lot more time reading code than we do writing it. So it's always worth bearing that kind of readability in mind. 29. Loop counters: Another common use of variables is to keep track of where we are as we execute a program. For example, one of the things we might want to keep track of is where we are in a lupus, that loop is iterating. So let's have a look at our way to do that. So we could start with a variable called counter and we set that to 0. Then we have a loop. So it will limit this loop to 30 dot times. So 30 times du. And then we'll put an end in here. Now I always find it's really helpful to put the type the end after I, after I type the du. So if I'm, if I'm using an Air for, if I'm doing something like a loop with a DO on the end, and we'll see lots of other examples later. I always find it handy just to put the end in straight away and then, and then write my code in the middle. This saves me forgetting to end a code block later on, coming up with some weird bug which can sometimes be difficult to find. So that's what I prefer to do. But anyway, so what we're gonna do is we're going to loop through this loop. And for each time through we're going to play a note. So we're going to play 50 plus. The counter will then sleep for a beat. And then we will, we will increment the counter by one. So it will say the counter is whatever the counter is now, plus one. Okay, so let's just walk or talk our way through this if you like. So the first thing we do is set the counter to 0. Then we say, do this 30 times. The first time through this loop, we play 50 plus the counter, which is 0. So we play 5050 plus 0 is 0. We then asleep for quarter of a second. We add one to the counter and we go back around this time through the loop. Then we play 50 plus one. We sleep for quarter of a second, we add one to that. So the counters now to go back through the counters to so he play 50 plus two. So we play 52 and sleep. And then we add one to the counter, so it's now three. We go back round, we play 5353, then we sleep for quarter or second quarter of a beat, and then we add one to it with 54 and so on and so on. And we do that 30 times. So what we should here is as we move, as we saw earlier, as we move up a number in the midi note value. So this number here, this 50, that should move that ball that does move up a semitone. So what we should here then is we should start at 50 and then we should, every quarter of a beat, we should move up. We should play a note of this up one semitone. So let's hear that. There we are. So that works exactly as we expected. Now, this is, again, such a common thing to do that Sonic Pi provides us with a shortcut. And this works like this, so this will work perfectly fine and it's absolutely fine to use this if you've got this in your head and it's easier for you to read, is absolutely the right thing to do. But there is a shorter version. I'll show it to you now so we can get rid of this counter variable. Basically, we can place it here. So we can say in-between two pipes, like so. And we can get rid of this here. So you can see this makes it much, much shorter. But we can say 30 times do. We can say, okay, include this counter. This counter will always start at 0. And every time we go through this loop, it will, it will add one to. It is such a common thing to do. There's a built-in function. It looks a bit odd. It's not as easy to read. I appreciate that, but it is, if you get used to it, it does save you quite a bit of code. Of course, this counter could be called anything you want is quite common actually encode to see this called I. This is just a convention across seemingly all programming languages. So I've used this in tons and tons of different languages over the years, but it's quite commonly called IAC could be called counter, you could call it whatever you wanted. You could call it Steve. So let's let's hear this. Again. Just a shorter version of what we did before. We can call this whatever we like, we just need to remember that it needs to be the same name inside the loop. So that is that. Okay, so just have a little play around with that and just make sure you really understand what's going on. Remember, move on to the next section where we're going to look at a few more programming concepts. So this time around some data structures which are built into Sonic Pi. 30. Lists: Okay, So there are a number of data structures built into Sonic Pi. It's a complicated name for a fairly simple concept. So we'll go through each one bit by bit. And they really are designed to just make things a little bit easier for you. Inside of Sonic Pi, There's lots of really useful building things, but we're going to explore them within this section. So you can see on the screen here that I've got a very, very simple program which is going to play a chord. Now, another way of doing this, just to save a little bit of time at a few lines of code, we could use a thing called a list. Now a list is just takes a number of values and puts them together, separated by commas inside square brackets. So let me just show you here. So let's put a, let's put asleep here. So we can have a list which is, which is here. So we have square brackets and then we put all the values we want inside that list. And then everything in that list will be we operate on, so it will play everything in the list. We could say we could just take the same value. So an A4, I, C-sharp five, C-sharp five, and a E5. If we execute this, but we're going to play this chord and then we're going to seek one beat. And then we're going to play this chord and we will see that there's exactly the same output. Let me just separate this byte. Two seconds. I think one was hanging on. Okay? So this is exactly the same as this. But we are, we've just put all our values insider inside of list. That means that we can move three lines of code onto one. We can equally. I've replaced this with midi note numbers. So we could say the equivalent here, which is sixty nine, seventy three, and seventy six. There we are. So it's exactly the same. So this is just a list of things. And in this case, we're asking that when asked him to play command, to play this list, that list contains all those things, but there are other things that we can do. So let's have a look at some interesting things that we can do. So let's create a loop. Let's leave that like that for now and then choose and make sure we put our ending. Now. It's a loop several need asleep. So it will sleep for half a beat. Now, what this is gonna do is if I just looked this like this, it's going to play this chord. Sleep for half of each. Play it again, sleep after we play it again. Now, I'm actually something that might be useful if we could pick one of these at random to play each time we went through the loop, we know we'd have a note within that chord. But it's just going to pick one of the things at that list of play rather than playing them all at once. The way we do that is with another randomization function. And we use randomization a lot in computer programming in general, but particularly this kind of music making code because it makes, it makes for some really interesting melodies and patents. So let's use the choose Kiba. So we've just put the list inside of parentheses. How many say, okay, well, choose me something that from that less than plant. So that's basically what this code is saying. Let's listen to this. Okay, so you can see that it's picking something from that lesson. You can see quite easily how something a little bit more complex or maybe a slightly longer list, might provide you with some interesting inspiration from for music and ideas. Now, I don't think we could do is we could, we could create a variable. So we could just outside here. We could speak and say, Oh, we could do it inside or outside. It doesn't matter, but just to demonstrate the use of variables. So we can say, let's create a variable called scale underscore list is equal to, and then let's cut out from them. Put this outside. Then we can say play something from scale, this scale list. This will work in exactly the same way, but we've just pulled this out now into a variable. So why is this useful? Why we might want to use this in various different places. We might say, might want to change this scale into a different scale. In which case we could just go and change them once and we could refer to it throughout our program. But just another example of using variables to store values. So this is our list. 31. Indexes: Okay, so what if we want to play a particular note about lists? And lists can be of an arbitrary length. We could have hundreds of notes in there if we wanted to, or a 100, you can store anything less than our case was just storing numbers and then playing them, but we can store anything in there we wanted by you can have hundreds of items within your list. How do you choose which one you want to play if you want to play a particular one. This is a thing called indexing. Or an index is, is it's just a way for us to tell the, tell the program which item in the list we want to play. And we could do it simply like this. So let's get rid of this randomization for now. So let's get rid of, Let's get rid of this loop completely. So if I play this now, is going to play all three of these accord. But if I wanted only to play this middle note here, then I would just put in square brackets a one. I can equally do this like this list. Maybe, maybe this is even simpler to see. So let's put this down here, the way that we had the list originally. So you can see I've got my list and I'm saying, this is my list. Just play me this item here. So this is a one. Now, why is this a one while Lissa are always 0 base? Let's have a quick look at a slide to explain this. Okay, So as I mentioned earlier, computers start counting at 0. So normally as we started counting, if you asked a chart account, they would count 1234, etc. Computers always start counting at 0. This is called a cross, just about every programming language. There are exceptions, but just about every programming language. So this is why the middle value within the three item list that we just saw. That's why in order to get the middle value, we actually chose index one because index 0 would have been 69. Index 173, an index to 76. So this is the 0 index. This is the index one, and this is index number two. Indexes always start at 0 the same as everything else. So whenever we do any county in size Sonic Pi. Okay, so when I execute this program, then we should hear indeed the number 73. So just to prove that, Let's, let's play a 73. And then we will sleep for a couple of beats. And then we'll play the index number one from this list. That we can quite clearly see that they are the same note. If I wanted to change that, I could play the first item in the list. I want, I can play the last item in the list. What happens if I try to play something outside of the list? Well, nothing happens. It's rather than throwing an error, It's simply, if we look over here on the logs, we simply it plays a rest. Now, there are other ways to play RESA. So we've looked at, let's remove this. So there's a kind of thing built into Sonic Pi. So we can play a restaurant there. So we could play, let's say a C3, C4, C4. I'm just making stuff up now. A E4. And then we can use this symbol here, this codon, that means arrest. And then we can play, let's say another three, A4. Okay, so now this is, this is not going to work in this form because we're gonna, we're gonna just going to play these four notes and nothing here because it's going to play a role as a core. So let's maybe go back to a less so we will have a scale, or this could be called anything. So my list is equal to this. And then maybe we can use that loop construct we had before. So we could say five. We've got five things, yeah, five times do we will use our counter. Again, we'll use AI by convention. There's our end. So we can say play my list. And then in square brackets we can tell it which index we want to play. The index we want to play is based on the counter. So again, this could be called counter, it could be called anything you want. So as we look through this first time, the counter is going to be 0. So it's going to play the 0th item in the list item, item 0, the first item. And then we'll go round again counter we incremented it will play this item here. And then the counter will be incremented. Replay this item here. Then we'll play this which is arrest, and then we'll play a four. Now, wanting to put asleep in here. Let's listen to this area. So two things that are ready. One is that we can use this special symbol inside, sorry, pi to indicate a rest. And secondly, putting this list inside a variable and then using the counter, which we saw as part of the iterations, using this variable name here to use the index to pick that item, offer less. So just have a look at this. This is quite commonly used. This kind of code is quite commonly used. So make sure you fully understand that before we move on to the next section, where we look at using some of the concepts we use so far to create a simple drum sequencer. 32. Making a drum sequencer: Okay, So we're gonna use some of the things we've seen so far to create a simple drum sequencer. So none of the concepts in here should be new to you, but they're probably the first time that we've really combined quite a lot of them to create something really useful. And this will help you to really begin to see the power of sight pi. Once you combine all these concepts, we've got, we've still got a lot more to learn, but, but we've got everything we need to build a drum sequencer now. So let's start off with creating some variables which will hold the sample names for the samples that we want to use. Very similar to what we've done before. So we'll just say hi hat is equal to drum underscore symbol, underscore closed. We'll create a snare, which we will call SN zone. So this is just the sample name that we're going to use. And we'll create a kick, which we'll use BD house, which is the name of the built-in samples. Then we're going to use for the kick drum. So the next thing we're gonna do is we're going to create three more variables, and these are going to contain the patterns for our drumbeat. So when we create this pattern, we're going to create a string and I'll explain that in a second. And it's going to contain x's and dashes or hyphens. So basically what we want to do is we're going to write a bit of code after that says, wherever we see an X play the sample, if we don't see an x don't play the sample and this will be the basis of our, of our sampler. So let's create the pattern for the hi-hat. So we're going to create a variable called high hat underscore. Underscore pattern. In here we're going to create a string. Now, a string is just a type of value that we enclosed inside double quotes like this. This says that this means that we can use spaces and whatever we want inside. But it's basically just a way of saying, treat this as a whole value. Even if there are spaces or other carriers in there, this is a whole valley. In here. We're going to put our drum sequence. We're going to make sure that we've got 16 characters inside here, because we're going to create a sequence. So that's got 16 steps, so 16 step sequencer. So let's have a look here. So we're going to create 16. Character says 123456789101112. Oh, no, I've countered that very wrong. 123456789101112131415. I'm going to end up with that. We'll end with a double kicks. So we've got 16 steps are, I went wildly wrong. There was only and the x's I think we're going to go kick, rest, kick, rest, kick, rest, kick rest, all the way along, then end up with a double-click. So we've got 16 characters there. We then create our snare pattern. So we're going to have a snare pattern which looks like this. So let's create a variable called snare pattern. And again, we want 16 items within our snare pattern. So we're gonna go hyphen, hyphen, hyphen, hyphen hyphen X hyphen hyphen hyphen, hyphen, hyphen, hyphen, hyphen. We can see because the font used inside the code editor is a monospaced font, meaning that every single character takes up the same amount of space. We can see that because we know we've got 16 here. If these line up, we've got 16 here too. But creates our kick pattern. As I said before. Sonic Pi really doesn't mind about whitespace. You can put spaces or carriage returns wherever you want to, just ignore them. So what I'm gonna do is I'm going to just add an extra spaces. So this all lines up nicely. We're going to create a snare pattern, something like this. Okay? And it really doesn't matter what your hi-hats narrow kick pattern looks like. This is this is what I'm going to go with for now. And then underneath here we're going to create a loop ending Command M or Control M to format the code. And then inside this we're going to create a nested loop. So we want to loop forever, but we want to have a 16 times loop inside that, which is going to step through this and decide whether we play a high hat, a snare, or a kick. Okay, So let's create our 16 times, 16 times du. And then we're going to use a counter in here. So again with the pipe. Remember we could do this by initializing the counter and doing a counter equals counter plus one or, or, or whatever in here. But this is the shortcut we're going to use because it's such a commonly done thing within, within Sonic Pi code. So let's create our end. We need to remember to put asleep inside our loop. Will sleep for a quarter of a beat in here. Then we're just going to use the simple F to determine whether. We should play each drum or not. So let's just say sample hi-hat. So we're going to play this, the hi-hat sample, which is going to play this variable here. So drum symbol close, but we're going to play if the hi-hat pattern, I can't spell hi-hat, high hat pattern. And then we're going to look at the index of it is equal to x. Now let me explain this to you. So the first time through the counter is going to be 0. And so we're going to say play the hi-hat sample, but only if the hi-hat pattern for index 0. So we're going to look at this hi-hat pattern. We're going to look at the first character within the hi-hat pattern. If that's an X, play the high hat, we will second time round the counter's going to increment the count is now one. This time round we're going to say play the psi hi-hat sample if the character at position one within the hi-hat pattern is an x well positioned one with 0 based. So it's the second character while it's not an x. So we're not going to play the high hat. So we can do this and let's listen to the hi-hat pattern. You should be able to recognize the hi-hat pattern from this string that we've got the top here. So it's going to play hi hat, rest, hi-hat rest, hi-hat rest, hi-hat rest all the way to the end until we hit two hi-hats. Because we're looping round, this is effectively going to be three hi-hats and row. So let's listen for that. Okay? So that's our basic sequencer. So all that remains to do is to, is to do exactly the same thing for the snare and for the kick. So all we say is play the snare sample. If the snare pattern at the position that we're at within the, determined by the counter, the index of the rat. So by the counter is an x. And let's listen to that. And finally, we can do the same for the kick. So we can say play the sample kick. If the kick pattern index of counter is equal to x. And again, every time we go around this loop, counter is going to increase, going to start off at 0. But every time we go around the loop, the counter is going to increase by one. So every time we go through the counselor increase by one. So if there's an x, that position within the hi-hat pattern, the snare pattern or the kick pattern. If that is an x that is going to play the relevant sample. Now it's going to do this is why we put the 16 times counter inhibitors. So we've got our loop, which is me, we're going to loop forever. But we're gonna do the 16 times loop inside, which means that we're going to do it. 12345678910111213141516 times that by which time this loop has ended. And we'll hit this one, we'll go back to the top and hit this will start a new 16 times loop with the counter reset, reset at 0. So the counter will be 0123456789101112131415. Once it hits 15, has been through the leap 16 times. Remember we're zero-based when we count, it will go back to the top and then the counter will be reset to 0. So we go back to the beginning of the string and we'll just go round and round and round again. So let's listen to our sequencer in action. And of course, we can change our pattern really quickly. Now, you're beginning to see the power of loops and variables of selection. So if I had just program that drum pattern in by playing samples are just using a sequence. So just sample, sample, sample we would have written are lots and lots of code. And if I wanted to change the bass drum sound, for example, or the, or the snare sound. I would've had to go and change that. And an awful, awful lot of places would have also been very difficult to keep track of. Where should I be playing? High hat and where shouldn't buy? Where should I be playing a kicker? Where should I put? By using this simple pattern here, just using some of the concepts that we've learned so far. We've got a really nice, very easily readable, but most importantly, it really easily changeable piece of code. Very easy for me to now go and change the pattern of my kick. So let's add a kick in there. Instead. We run that. We've got a different kick pattern. We could change the snare drum to be something else. So I think there's one called snare generic. So again, very easily readable code, but also easily readable and understandable and easily changeable. So there we are. So it make sure you really understand this, have a play around with it. Change some of the patterns, change some of the sample sounds. And why not go and introduce another drum into the sequence. So perhaps introduce a cow bell or a, or an open symbol into that pattern and see how you get on. 33. Playing patterns: Okay, So earlier on we looked at a way of using a loop to iterate over a list or list of notes to play them each in order. But actually there are a couple of different ways that you can do this inside Sonic Pi. And as you'd expect, Sonic Pi has got you covered with all the common programming tasks that might be useful for music. So actually there's a couple of built-in functions called play pattern and play pattern, which will allow us to achieve what we want to do. So let's have a look here. So we had a list array which adds some values in it. So we could call this, let's call it my pattern again. So we just create a list. Remember our list is just a bunch of comma separated things within these square brackets. So we'll just choose some numbers here. Sixty nine, sixty three, seventy six. I'm pretty sure that's what we had before. And then we can say play underscore pattern. Play underscore pattern. My pattern. So let's listen to that. This is exactly the equivalent of doing this. So let's just comment this out. So this is not going to execute, so it's exactly the same. It's just that it's sometimes a bit easier to store these things into a variable. But either way is fine. So what this is gonna do is by default, it's going to simply play every note within that pattern, within that list. And it's going to sleep for one beat between every note that it plays. If I want to change, I can use a different method called play pattern underscore, timed. And then after the, after the list, I just need to give it a value for how long I wanted to sleep between each note. So I said just say comma nought 0.25. And this is going to play this list here in order and rest for nought 0.25 between each note. Okay, there we are pretty simple. And again, we could do much more complex things there. So we could say we could introduce a rest like we did before. And then we could do something like what? We could do the scale back down, right? So we'd do 7673. Well, the arpeggio back down and 69. So this is gonna play all the way up. It's going to restaurant a quarter beat and then all the way back down again with a coral reef between each. Note. That we are pretty simple. So let's have a bit of fun. So let's use a synth, and we're going to use a synth profit. We're going to create a loop command M, and we're going to play a time pattern, but inside that, so let's play comScore pattern, underscore timed add. We will create a lesson with an r square brackets. And inside that we're going to create a, a series of notes. So let's go for this. Let's go for S3, v3, g3, G3, B3, and a C4. So those of you with some music theory knowledge may have spotted that that is a C Major seven arpeggio. Well done if you did. So we're gonna go up the arpeggio and then we're gonna go back down. So a B3, patrick G3, and an E3. I'm just going to loop around, around, around that. And we're going to rest for nought 0.2 of a beat in-between each thing that we play. And we'll end up with something that may sound familiar. A bit of fun with, with with patterns. There. 34. Chords: Another thing that we have built into Sonic Pi, our courts. So let's have a look. To play a chord. We can simply say play a chord and we just need to tell it which color we want it to play. Let's play a D3. Then we need to tell it what type of core we wanted to play. So there are a whole list here and you can see it's come up in the code complete. So there are a whole bunch of cores that are available to us and it really is a kind of extensive list of chords are going through. But for now, we can just say, okay, plays a major chord. Let's play that. There we are. So that's played as a D major chord. There are lots of types in there, so we might want to play a minor chord. We could play a minor seventh, some sort of diminished chord. Okay, so there are a whole bunch in there. And as you can see, the code complete is really excellent. So as soon as you start to type equal, it will give you all these. So have a play around, look at the different types of chords in here and this saves you create in that list and working out. Values are the notes that need to be within each chord. So let's say we've got a D3. We're gonna do a, a major seventh chord. Now we can actually use indexes to tell us which note in the core to play. So if I was to put an index of one on this, this is going to play the second note in the D3 major seventh chord. Again, if I change this index to be okay, so I can use, use code here, use indexes to pull out the notes within courts. I can also play in versions of chords. So let's get rid of this index for now. Let's change this to a minor chord. And I can say, okay, well, play me the first inversion of this. Play the second inversion. The third inversion. There we are. So lots of really useful things, really useful functions built into the courts. I could also play the chord as a, as an arpeggio. So let's just remove this to keep it nice and simple. But instead of saying play the chord, I can say play, play pattern cord. By default per play pattern is going to leave a rest of one beat between each note. But if I want to change the speed of the arpeggio, I can say Play button, tide. And I just need to put the end here so we'll say five, so quarter a beat between each note. One more thing I can do with play pattern Simon is I can actually give it different values for the time that I want to respiratory notes. What this is gonna do is it's going to alternate between the two. So it's going to sustain for 0.25 for the first note, 2.5th for the half a beat for the second note, quarter for the third half of the fourth. And we'll just, we'll just flip between these two as I go up the arpeggio. And you can see that reflected in the log over here on the right-hand side. We also have the concept of chord degrees. So if you've done much music theory, you will know about core degrees. So sometimes when we talk about cause we talk about the common chord progression. So we talked about maybe 156 for being a common chord progression. These are actually built into Sonic Pi. Let's just write a little example just to demonstrate this. So let's set the BPM to be a bit, a bit higher. We're going to use a piano. And then we're going to create a variable which is going to store up aggression. So our chord progression is going to be a ring. Now, don't worry about this word ring for now. We will cover it later on. Just for now, just type in the word Reagan. I'll explain exactly what this does later on. But basically it's a list that goes round and round. So we just type in these which are kind of common symbols, right? So we use Roman numerals for our four chord progressions when we talk about music theory. And then we'll create a loop and we'll go round eight times. Inside the loop, we are going to need to remember to end. Let's remember to put our sleeping as well. So, so in here we're going to, we're going to play the chord degree. So I'll explain this as I, as I typed. So we're going to say chord degree, which is a built-in function much like chord or others that we're going to see in a minute. Am I going to say play, play, play the next value in our chord progression. So this tick will see it again later on. But basically, just to, just very quickly, a ring is basically like a list, but instead of going off the end and get nothing, if it gets the only goes back around to the start. So we'll go round and round and round. And tick is just a way of telling it, saying, get me the next thing from the list or from the ring. We're gonna be in S3. This is gonna be the key that we're in. We want to be in a major key. I can spell major. And then we're just going to add one more option to there. So we'll set the release remember from the ADSR envelope. So if we looked up before, we'll set the release of four. So what this should do is it should, using the synth piano is going to play. Each note is going to release over four beats, which is why we've got the sleep for here. We're just going to play on a C3 major scale, or C3 major key. We're going to play the first chord, the sixth chord, the second, and then the fifth. 35. Scales: Okay, so on to scale. So some scales are built into Sonic Pi. Actually quite a lot of scales are built on psi prime. You'll see that now. So let's start off with a play pattern time. So we're going to want to play every note in the scale. So we're going to play a scale. And then inside there we need to say what is going to be the root of our scale. So we're going to see a C3, and then we're going to choose from this certainly long list of scales. So there's a huge amount in there. We can see all sources as blues scales. There's all kinds of different world music scales inside here, or metric scales. There's modes of seeing. Eolian. There's the blue scales again. Chinese girls, crotchet scales, diatonic, diminished, Dorian mode, Egyptian. There's a, there's just a lot in here, so it's definitely worth having a split through this list. We can see down here we've got all sorts of things. So we're going to choose a common one here. So we will choose the major pentatonic here. Then we can select how many octaves we want in our scale. Do that just with a num octaves. So we say num octaves and we'll say we want three oxygens with large-scale. I'm going to say we're playing patent time to remember so into say how long we want to rest between each note. So that's nought 0.5. I must set the, the release of the notes that we're going to play. But set that nice and short to nought 0.25, just so if we don't do that, then all the nodes will run into each other. We weren't here. A nice crisp scale being played, so let's play that. Okay, so that's the scale. So there are a whole bunch of built-in. Now, let's just comment this. I'll show you one thing. So there's command within Sonic Pi is a Ruby command, but, but then Sonic Pi called puts and puts is going to allow us to right what we want into the log. So for example, if I was to say butts, Sonic Pi is great. When I run this, it's going to output that to the log. There we go. So we can see in there. Now, this can be really handy points during your programs just to output some it's an OK so you know where you are. So you know, when you're inside a loop or when you're outside of your particular part in your program. There are some other things that you can do with put, so you couldn't get the outputs of some built in functions. So for example, if I wanted to say output round, this is going to output to the log of value between naught and one. If I create a variable, let's call it message equals hello. And then I output or puts my message. Now we are, so it's grabs the value of that variable and an output that into the log. The reason I got here anyway, I've gone off on a bit of a side quest. But the reason I put this here is actually I can get all the scale names out into the log by doing, doing this. So I can say output scale NEEPS. We'll put scale names. There we are. So what will end up with in the log is a list of all the scale names. And you can see there are lots and lots and lots of them. I'm probably going through a bit too quickly, but if I didn't, we'd be scrolling for days. So you can see in there. So definitely have a look through that list. You can use the code that we've got here. Just uncomment this thing here. Come on that for now. Use this kind of CO2. Just, just listened to, listen to some of the scales, perhaps play some of them with different sense to see what interesting things you can get up. That is that so one thing that we could do with the scales, for example, is we could randomly play some things up the scale. So let's have a quick look there. So we could say, let's take the C3 major pentatonic three octaves and will lead us all exactly the same. But let's choose not to play the whole pattern, but just to choose something from that. So we'll need to just change this because we're not play a patent timed anymore. Let's just make it nice and simple. Let's do that. And then let's sleep for half a beat. So let's put it all in a loop and run that. Again. If you've typed this code into your computer and you play this, it will play exactly the same sequence of nodes that I get. This is because the randomization side, Sonic Pi is kind of pseudo randomization. So that we're sure that we always play the same every time if we want to. If I want to change that, I can, I can change the, the randomization seed. So choose the random seed, I can just make that 606. And this time we'll get a different, I can make it 99 different shapes. But again, as long as that random seeds stays the same, it will be the same tune every time. 36. Rings: We mentioned brings before. Let's have a look at rings. So I bring is a way of ensuring that we don't run off the end of the list. So let's demonstrate that. So let's, let's use the puts ground. We can output stuff to the log and see it now. So let's say if I create a list, so 606467, this is the one we used before. I think I want to output to the, to the, to the log the item number one, so 01. So this should output to the log number 64. There we are. So we can see the number 64 output to the log as we would have expected. But what happens if I asked for Item number nine out of this list? We can see I got a nil. And the reason for that is that there's only three items, so item 0, item one, item two. So nine is out of range, it doesn't exist, it doesn't exist within that list. So it tells me it's nil. Now Sonic Pi, when you using the play command, actually handles this really nicely and gives you a rest instead of throwing an error. But we can say this could easily catch us out. So for example, let's, let's put this into a nine times. Do we're going to use that shortcut again to get the counter and pull, bring this down into here. So what I am expecting to see here is for it to output 60 on the first time round 64, then 67, and then six Nils. And there we are. So 606467 and then a bunch of nails. So how could we do it? So that when 606467 and then background, and you can see that this is, this could be a really useful thing as we create a selection of notes that we wanted. Now we want to just loop round and round that selection of notes in a short sequence. Well, we can do that by making this list a ring. And there's a couple of ways we can do this. We could say, we could put dot ring after it. And what I bring is it's just basically the same as the list. But when it gets to the end, when you ask for the item off the right hand side of the list, it loops back around and brings you the first one. So it just goes round and round and round. So what I'm expecting to see here, 606467 output three times. And there we are. So we can see it's gone through the list and then background and then background again. And it will just keep going and going and going forever, round and round around the list. So that's really useful. Another way that you could write this is, is you could just create the list in a slightly different way. So instead of using square brackets, use parentheses and just say this is a ring. This is exactly equivalent to the code we had before, and it will run it and it will run exactly the same. It's just a different syntax if you'd like a different way of writing, so you can use whichever one, whichever one you prefer. Okay, so let's just, just to prove a point, let's just, let's play that instead of putting it and then we'll we'll put asleep imagery the two in-between them. And that we are. So we can see that that brain just went around, around, around three times. If it wasn't a ring, we would have ended up with this. I would have tried to play from this list. We don't play the three notes and then, and then had six rests. There we can see the outlet recipe and output. So by making that ring either using the format we had before or by saying dot ring. So actually scales and chords are both rings. So we looked at scales and chords before. They are both defined as ring. So you can just go round and round and round, both scales and chords. And this is why we made the chord progression in the previous session a ring, because we wanted to go around that chord progression twice. So we could do the same way as we've done here. So we could say the same as we did with the scale. So instead of doing this, we could say play patterned or play Pat and timed. Both of those things are work on a ring. And then we can again no, 0.25225 to tell it how long to slip between each one. And just, just to reinforce this, this is exactly equivalent to create an art ring in, in this way, just with the keyboard or the front. It's really up to you which one you prefer. 37. Ring functions: Okay, So there are a number of things that we can do tutoring. So let's, let's just make our ring a little bit longer so I can show you some of these things. There's some additional functions that we can we could use. So 606264 and then we'll go 656769717072. And that should give us this. That beeping is getting a little annoying. So let's pick an A-list change out. So let's use a piano. Okay, So there are a number of things we can do with a ring. There's a bunch of functions built in that can be really useful musically. And we just add them onto into the ring. So we can say play pattern time, use this ring and we say use this ring, but dot reverse. This is going to play the ring backwards. We could shuffle. So this is going to play every note within the ring, but it's going to play them in a random order. But it'd be the same order every time because we, we've got the pseudo randomization within Sonic Pi. Again, if I want to change that order, I can set the randomization seed to be something different. I can just only play the first five elements. So I can say just take the first five elements and from this ring and play those. I could say I dropped the first five elements. When I say dropped the first five elements, it means don't play these and just play, just play this. There are other things I could use stretch. So this is going to repeat elements that stretch can be whatever I want it to be. So let's say three this time. If I want to repeat the whole ring, I can say repeat and say, let's repeat this one twice. And again, I can make this any number I want inside here. I can use Mirror. Mirror is interesting. Mirror is going to play all the way up the ring, or in our case is a scale, but the ring could be anything. It doesn't have to be in this order, but I've made it a ascending scale just to make it nice and clear what's going on. So it's going to play all the way through the ring and then it's going to play all the way back through the ring in reverse. Now you'll notice that it played 60 sixty two, sixty four, sixty six, sixty seven sixty nine, seventy one, seventy two. And then it played 72 again and seventy one sixty nine, sixty seven. So if I don't want which is quite common, I don't want to play this one twice. I just want to go all the way up and then straight back down, but not play this the middle one or the end one depends on which way you look at it twice. I can use the word reflect. I can use the word reflect. This is only going to play the 72 once. Okay? So there are a whole number of functions. These are the most common ones. And you can dig through the dock, through the docks in the bottom here to look for the rest. But one thing you can do is to chain these things together so I could say, okay, So I'm going to, I'm going to place one in reverse. But then I want to reflect that. So I'm going to reflect, reflect the reversed ring. So it's playing from the end all the way down, all the way back up again. And I want to repeat that three times. We are. So again, a ring is incredibly useful. Data structure is the final data structure that we're going to look at within Sonic Pi for now, it is exactly the same as a less than we can access things through indexes, etc. But it just goes round and round and round so we can never run off the end of a ring. Hence the name, lots of really useful functions to it. And I'm sure that you can see there's lots of musical applications to the functions that we can apply two rings. So these are functions we can apply two rings. In the next section, we're going to look at functions that we can create for ourselves. 38. Custom functions: So now we're going to look at functions, which is another way to organize our code to keep it nice and readable and keep chunks of it reusable. Now basically a function is a way of organizing a piece of code and giving it a name, but that Coburn actually run until we ask it to. So let's dive straight in and see how to do this. So let's go into the code editor here, and I'm getting a bit fed up with that beep noise. So let's use a synth. So we'll use the profits in. And we'll start by creating a function. So what we're gonna do is we're going to create two functions, one called verse and one called chorus. What are some unlabeled us to do is to define averse and of course, for our song, and then we'll be able to call it. That way. We'll be able to organize our song in the way we want it to do without having to repeat the same bit of code many times for each first, for example. So let's start with defining the person. So to define a function, we use the keyword defined. Then we need to give our function a name. So in our case, we're going to call it the verse. We finished with the do. And because we're going to do, we must have an end. So there we are. Now, anything that we put inside this block is not gonna be executed when we run the code. When we, when we click the Run button until we call that particular piece of code. So we'll keep the reverse, nice and simple the code nice and simple inside our function. We'll just go through a timed pattern. So let's say play pattern timed. And let's create a list inside are less than. We will record. Our code will be a D4. And this is gonna be a major chord. And that'll be followed by a, another chord. And this time we'll do a, a C chord. And this will be a major chord. And then finally, we will have a G chord. Okay? Am I going to play each of these quarters or is a timed pattern? So we've used play pattern time. So we need to tell what Sonic Pi, how long to asleep between each, each part of the pattern. So we're going to sleep for two beats. If I run this code now, nothing will happen. All this happened and we can look over and the log here is that we have defined the function first, but we've never actually asked it to execute the code inside there. So to execute it, or we simply need to do is type the word verse. And that is saying to it, please execute this function called verse here. And this is exactly the same way that the other functions that are built into Sonic Pi define things like play in play pattern and play pattern, tiny, etc. They're just, they're just functions that we're asking you to asking it to execute. So now when I press play or run, Here we are. So it defines the, the verse here. And then when I call verse, it will execute the code within side. So I can define another one. So let's define one called chorus end. And inside there we will just play another pattern, but we'll play different one. So same again, but we'll use in different courts. So inside our core us will have an A4, a major chord, followed by a C, again a major, and then a D major chord. And we'll keep the same, the same sleep in-between each call to keep the same tempo. So now we have a chorus so we could call him, instead of calling verse, we could call our chorus. Okay, so now we can construct a song simply by calling our function. So maybe we'll have averse, followed by another verse and chorus and then a final verse. Quite a simple book, but common song construct. The first versus the second verse. Now chorus. And the final. Now to reorder or solve, we can just change the order in which we call the functions. And to change the course, perhaps we think that A4 is a little high. So let's change that to an A3. And now when I play it, and again, we can, we can reorder this so we can cut this from him. Maybe verse chorus and then two versus. Now we're going to get a chorus. Our course is changed. Then finish with to go ahead and do the same and create a verse and the chorus. And what you could do also is to create a midline or a pre-chorus or another function. And use this to construct a short song like I've done here. 39. Function parameters: Now we can also pass parameters to our functions and we do that like so, so in averse. So here we've got a verse and we've repeated twice. But another way to do it might be to say, okay, Play me diverse twice or play with reverse once. So I can go to verse here and say, very similar to how we did this with loops and counters. We can just inside pipes here, we can just give a variable name so we can say repeats. And so this variable will be passed to the function when we call it, and we'll see how to do that in a second. It's very simple. And then we can use that variable inside the function. So we can say repeats dot times du. Then we can end here. So it's going to repeat the number of times that we pass to this function. So in here we can say we just play this first once. And then here, instead of having a second verse, we can say, okay, now I want you to play the first twice, twice. Great. So one last thing that we can do is to give a default value. So for example, if I was to forget to call verse or pass a one to this, to say just repeat this first. Once. The following is going to happen, we can see we've got the wrong number of arguments. The arguments are what we've, what we've got here. So these are, these are, these are the arguments that we pass to the function. We can see here that we expected one argument to be passed either number of repeats, but we actually got 0 because we forgot to pass the number repeats of the function. One way to fix that is just to go and put that number back in. Another way is to say, well, if I don't pass anything, then just play it once. And we can do that by setting a default parameter, and it's very simple to do. So we can say where we declare the parameter up here for the function. We can just say equal to one. Well that's gonna do is say, if I don't pass any parameters, than just assign the value one to the variable of repeats. And if I do partially a value, then use that value. So let's go back to our original configuration, where we had two verses, a chorus and then one verse. But we're not going to pass a parameter this time, and we're just going to rely on this default parameter being here. There we go. So obviously we could do the same to our course if we wanted to. We could call it repeats, we can call it times, we can call it whatever we want to really. Again, we'll declare a default value here. And then again, we'll say repeat stop times, do. And then we'll need an end for that loop. There we go. So that's how we define a function and assign parameters to that function or declare parameters for that function, parse them in and how we set default parameters for what we want to do if we don't pass a parameter or a value for a particular parameter. So you can see here, there's many, many uses. This very simple example where there are many, many uses for functions from our code has just a way of organizing our code, making easy to change. We don't need to make the change in one place. For example, if I want to change the verse and instead of a C, we want to put an a, just make that change. And every time I call the first function, that change will be reflected. So a great way to make your code really nice and readable. I can easily see that this is the verse and the chorus. I can easily see the structure of my song. Like I said, this is one simple example of using functions, but I'm sure you can imagine many other ways to do it. So have a go at reorganizing your code and using functions to make it really nice and clean and readable and reusable. So we've been doing a lot of programming. So in the next section, we're going to take a little break and we're going to get back to some sound design. 40. Effects in Sonic Pi: So as well as being able to use synthesized and samples within Sonic Pi, There's also a whole bunch of built-in effects. And these are very much like the effects that you would apply to a track or two and instruments in your DAW. Or if you prefer to play analog instruments, perhaps using guitar effects, pedals, that kind of thing. But you can see there's well over 40 different effects built into Sonic Pi. So let's have a look at how we use them. To demonstrate these effects. We're going to use the sample that we used earlier that I've gotten my desktop. So let's remind ourselves how to do that. So we're going to play the sample, which is in users. Steve. It's on my desktop and it's called b21 dot. Let's just remind ourselves of what that sounds like. So to apply effects to this, all we need to do is wrap it with a width FX blocks. So Let's go to the beginning here, we say with underscore effects, and then we give it the name of the built-in effects that we want to use. You can see all the effects down here in the bottom. And you can see here's the same list of effects I showed you before. So we just need to give it the name. In this case, we're going to use a river. So we can say with effects codon, reverb, do we need to end that block? And so when I play it now you're here, that's a reverb effect has been applied to that sample. So it doesn't need to be a sample. It could be a synthesizer, it could be a simple plane command. But this sample, particularly, because it's a drumbeat, it shows off the effects particularly well, they're particularly easy to hear. But we could change this affects to be this effect to be anything we want. So we can look down through the list and find something we might want to apply a flanger, for example. So let's change the reverb to be a flanger. Or we could change it to be a distortion effect for a dirtier Sam. 41. FX options: So as with many of the items we find inside Sonic Pi, there are a number of parameters that we can apply to effects in order to customize the sun we get. So let's start with adding an echo effect. This is like a delay. So we'll say width affects echo. Do. We'll end that block. And then to keep this nice and simple, let's, let's just use a simple place. So we'll, we'll play a note, a 55 will sleep for two. Maybe let's use a sample. We could use the cow bell. We'll sleep again, and then we'll play one more note. So we'll play, I don't know, 67. So let's listen to what that sounds like. Okay, so that's what an echo applied to all of those notes and samples. But we can actually change some of the parameters. And you'll find that as we look down here, we can, in this list, you'll see that every Effects has got its own set of different parameters that you can apply. So let's just look in here for echo. Okay, and we can see in here that we've got things like the phase, the amplitude, and mix the decay. So if we look at, look down this list and we can say, we can see that the phase sets the time and echoes, or the sign between echoes in beats. So let's change that. So all we need to do the same as every other parameter that we've been passing around. So we hit comma, we then say, let's set the phase equal to, and we'll set it to half a beat. Let's listen to that. And there we are. So a much slower repeats on the echo. There. 42. Chaining effects: Now we can nest effects as well. So when we nest affects, all we're gonna do is very much like nesting loops. We're just going to put that block inside another block. So let's add a reverb and I'll show you how to do it so we can add another effect on the outside of this. So we'll add a reverb this time. I will need another end on the outside. We can see that we've got this affects block, which is the echo that we just created. And now we've wrapped that inside a reverb. And you should think about the audio flowing from the inside out. So the first thing it's gonna do is going to apply the echo effect, the delay effects the echo effect. And then it's going to apply all of that to the outer block. So it's going to add a reverb to the echo. The echo be applied first and then the reverb. This is very much like the way we chain effects pedals or, or effects units together on audio. So you can use really, really deep nesting for some really, really crazy or innovative sounds. However, applying the effects uses quite a lot of system resources from your computer. So just a little warning if you apply too many facts you were early or you may notice some performance issues. But to spine. So let's run this and we'll hear now that we've got an echo with a Reverb on top. 43. Taking control: So on occasion, we may want to be able to control a sentence already running. In order to do that, there's a function built into Sonic Pi called control. In order to use that, the first thing we're going to do is capture the output of the sent into a local variable. So we'll create a variable called my synth. We'll create a variable called myosin. Into that we will capture the output of a play command will play a midi note 40, and we'll set the release to five. This note will still play, but the output of it will also be captured into that my synth variable. We can then do a little sleep, take a little break, and then we can use the control function to change things about that synthesized so we can say my sin. We could then set a whole bunch of values. In this case, we're going to change the notes and we're going to say, okay, now play a 45, will sleep again, will control the synth again. We'll change the note to be a 47 this time. Then we'll take a longer sleep. And finally, we will change the note again to a 40. Now this is, this is a particularly useful function to use because if you remember, we set pan and amplitude and cutoffs and things like that before or when we set that, we said that it only applies to the current function. So when I do that, if I was to do a play 14, set the panel the way to the left, I would need to set that pattern for every single note that I played. Now I can, I can create my sense store. It, creates this release, for example, here. I can store that in the output by center. Now I can control my synth. I don't need to define the release every time. And you can imagine if I had a complex envelope and I said a lot of values in there, it means that I only need to set that on the first note, the first time That's int is used, capture the output of that into a variable, and then I can just make the adjustments that I see fit probably just to change the notes rather than having to set all those parameters every time. So let's listen to that. So the reason this is particularly useful is that early Rome, when we look to the play command, we talked about amplitude pounds. We looked at filters as well with cutoffs and resonances, et cetera. And we said that, that those parameters will only apply to the particular play command that's been executed. So if I wanted everything pan to the left and I wanted to use the play command, for example, I would need to add a pan minus one to every single note that was played. Whereas now I can set that on the original, on the first note, capture that the output of the synth into a variable, and then I can use that throughout. So I don't mean to set an envelope on every single every single night. If I want to keep the envelope the same, the power and the cutoff, the, the filter resonance, et cetera. So let's demonstrate that a little bit. Let's use a sentence. So synth will use this base foundation and we need to do, and then we will end this synth block. So now it's gonna do exactly the same, but it will use this base foundation synth. So I can add my parameters in here. So I might say the, for example, I can set the patterns or minus one. And what this is gonna do is rather than having to have powered minus one after every single play Command, I now set it here. It's captured within this variable and the parameters that I've applied here, I can control throughout or applied throughout. Now there is a slight restrictions to this. So things like AMP for amplitude with the volume, the cutoff, pan, things like that can be changed once a synthase started. But you can't change ADSR envelope parameters. So I can't change the release once a, once a synthase started. But I can control other items. So like the pan. I could in here, I could say control my synth and then I can set the note of 40. But on the final one, I might pan it all the way to the right. You can see again, this is another way of using Sonic Pi to take shortcuts to stop you having to repeat yourself all the time and really control the synthesis playing. So have a play around with the options in there. And I think you'll find it. Like I said, it's quite an advanced function, but I think you'll find it's very useful. 44. Controlling note slide: Another thing that we have when we use the control function as we can use a thing called note slide. And this is kind of like a glide or report them into effect. So we can add this when we declare the original variables. So let's, let's add it here. So it's just a matter of added another parameter or another option. We can say note underscore slide. And we set one. So again, everything in Sonic Pi when we prefer to time, It's the number of beats. So in this case it's going to take one beat slide from one node to the next. So let's hear what that sounds like. Necessarily. Again, I can make this really long or much shorter. We can hear a slight in, much more quickly between notes. Now. 45. Controlling effects: As well as controlling sense, I can also control effects. So let's, let's try that. So let's apply an effect. So exactly as we did before. Let's apply this one's quite good. We'll apply the wobble effect. Here. We need to use the pipe operators to provide a variable name. This is how this control works with effects slightly different to the way it works with synthesizers. So we just give it a variable. It doesn't really matter what their variables called. I'm just going to call it f x. So I will have an n block as well, or we will end the block as well. Then inside there we will use a synth. So we'll say with synth will use the profits n for that one. Then we'll just add a little bit of code inside this with synth block. The block works in exactly the same way, really is the huge synth that we use in command that we've used earlier. You sent me tend to place near the top of our code and it will use that same throughout with synth. Just says, okay, just use this synth between the do and the end of this block. So it's just a way of constraining that really. So let's say in here will play a 40 with a release of four. We will then sleep for four, and we will then control that effect. So what we're gonna do, in fact, let's just play that before we start controlling things. So you can hear the wobble effect as it is by default, will then begin to control that affects same, same method name. So we'll say control. This time we need to pass it this variable here. So this variable that we declared at the top. So it knows which affects or effect that we are talking about. This time, we will set the mix to not want to. So this is the amount of wet signal that is going to be output. Will control the effects on them, will play again. We'll play a different note with, again with a release of four. So you'll be able to hear the change in the mix of the effects are how much of the effect is output between the first and the second note. So you can hear that much more of the dry signal got through in the second note that was played. We also have some options for sliding effects. So let's just, let's just remove this. In this case, we can set a few of the parameters that are found inside the wobble effect. So again, down in the Help panel here we've got a list of all the list of all the effects. When we click on it, we can see all the parameters that we can set. So let's set a couple of parameters. So let's set the phase, the face to one. We could also set a thing called the Face slide. And we'll set that to six. So inside here then we'll, we'll, we'll play our synth will just make that lasts a little bit longer so we can hear the whole of the face slide. Let's hear that. Now. Then we can control that. So we can say control the effect as it's playing. And we can set the face down to something much, much shorter. Okay, So as I said, the effects are slightly different. We need to give it a variable name between the pipes when we declare the effect. But you can really hear that last example that the effect is being controlled as, as it's happening. So we only play one note, but the effect, because we set the release to be a long time, the effect is actually being changed as the note is played. 46. Live loops: Okay, so time to talk about live performance. So there is a particular co-constructed that's built into Sonic Pi, which really does enable live performance. Let's, let's consider a loop that we might have used in the past. So let's say due and then end. Then in there, we'll do something simple. So we'll, we'll play 60 animals sleep for one. Let's, let's play that. Now this is going to keep going forever. But what happens if I change this note? Let's change this to an 80. I'm just reminding. You can see that the loops continued to play and just another loop is added on top, on top, and on top. Now this is not ideal for live performance is the thing that we really want to do when we're performing live. And Sonic Pi is to be able to go and make changes to our code and have those changes reflected live. So not separate loops playing on top of each other, but actually change the loopless running as it's running. So the way we do that is through the use of lively. So let's do that. So all we do is very similar constructs in the loop, but we use the word live underscore loop instead. How about we do this? We need to give this a name. So let's just call this foo. So it'll become clearer later why we need to give them a name. But now when I run this, I'm doing exactly as you expect, looping around playing 60 monks rather. If I change it to 60, listen to what happens. If I change it to 70. So cleverly, Sonic Pi is able to detect the change and make that change live as, as my program is running. Now this has got, this opens huge possibilities for, for live performances. And you'll notice it was very clever that it didn't make the change immediately. It waited until the right points. So if I change this to asleep for 234234. Now if I go make this change and changes to 55, and I do it immediately after a note. You'll notice that it waits and continues to sleep and doesn't actually restart the loop until the right moment to see if I can hit it right. So we'll always keep that internal timer running and we'll continue the loop and won't make that change until the next time they executes, rather than executing again immediately. So this gives us great possibility. So we could, for example, let's set this to something a bit more affordable unless that sleep back to a shorter period. So we could, we could do all sorts of heroes were replaying live. So we can say sand can change this to three or three. And we can talk as much code in here as we want to inform us and it won't actually be executed until I press Command R or press the Run button again. Slowing us down. I'm so sorry. Sorry. The facts. Just riba. Change the notes. The notes. So you can see what's happened here is I haven't I've added another note, but I haven't been asleep. So it's effectively playing both these notes at the same time. Another synth. And there we go. You can see how we are able to make changes to our code as much as we like. And then when we press Command or Control R or hit the Run button, then the next time round that loop is executed, then the changes will be made life. So again, a fantastic way to kinda be able to perform live. Start with a initial code base, our initial piece of code, and then go and make your changes life to really add a performance element to it. So we can have multiple live loops running at the same time. So remember before, if we had something like this, if we had a loop do hidden here, we, let's, let's, let's just play a note and then end. Then we might have another loop, which might play a, play a cow bell. So what's going to happen here? Hoping each but asleep. The same here. Now of course, the second loop never actually placed. We never get to hear the cow bell. And that is because this loop is going round and round and round forever. So the sequence of the program flow never actually makes it down to the second loop. Lively. Does this slightly differently. So if I change this to be a live loop, and we can, again, we need to call it a name. So let's call this one foo, and change this one to a live loop and call this one. Bar. Will now see that both loops play at the same time. So let's just make sure that we can hear the sounds. Let's just change the sleep inside here. There's gonna be a bit of a weird rhythm, but it will mean that we can hear both sounds playing at the same time. So this means that we can have multiple loops run at the same time. And you can see this would be really useful for live performance. So where we want to have a, perhaps a, a drum pattern play a melody, maybe some chords or baseline. And we can have all of those playing independently within their own loops. At the same time. It keeps the code nice and clean, really easily, readable. And we're able to change it in real time as we're performing. 47. Live performance with live loops: Okay, So earlier on we wrote a sequencer which looks a little like this. Let's just remind ourselves of what this sounds like. This is great, but I'm not ever so useful for live performance. So how can we take this code and convert it into something that might be a little bit more useful and then perhaps add on a baseline or something. So let's have a look at what we could do. So obviously, we need to start off with a lively per mil core. This Trump's. So that's all changed. We need to do now so I can go in here and I can run this. I can change the pattern live. So let's add three kicks at the end. We can hear them. As part of our performance, we change the kickback. So let's add another live loop. This time, I'll add a baseline. So let's create a live loop. Do we need to give it a name? So let's call this the library base. Let's remember c, n the loop. And in, inside this loop then we'll use a synth. So we will use, you will use the superstore. And then what we'll do is we'll have a, a loop in here which looks 16 times. And we will end the loop. And then inside this loop, we will play a note from the minor pentatonic, minor pentatonic scale. So we will play from a scale based on midi note 40. We will play a minor pentatonic scale. And we'll just choose a note from that scale. A couple of other parameters just to make it sound a bit better. So we'll set the release to be 0.3. And we'll say only play if one in two, so with a probability of one and to play one of the notes. So just choose a note at random from the minor pentatonic scale. But then need to sleep because we're in a loop. So we will sleep for 0.25 or quarter repeats. And here we go. So let's just, let's just run this and hear what it sounds like. That sounds fine because we are playing at the same kind of rhythm and both the sink, because both started to play together. However, one of the things that you might want to do in, in, in a live performance is to add a new lipid, or quite commonly the Live loops you might construct beforehand and then comment out and then uncomment. But let's, let's pretend I could just cut this into my clipboard for now and we'll start this one running. So let's pretend I typed this back in now and I'm going to hit the Run button. It doesn't sound as good this time round. It's not in sync with the, with the trumps. The bass sounds out of time with the drums. Now this is a really, really simple way to fix this, and it's built into Sonic Pi. And all we need to do is inside, are inside our libraries. And this is why we give our live loops and name. We just say simply sick this with the drums. Sick this with the drums. So now when I introduced this live loop, if I just cut this to the clipboard again, paste it in. When I press the Run button, it's going to wait until the right point in the library to start the baseline. So there's always stays in sync in a matter of when I press Run. So now I'm like performance is underway. We could choose to change a few things. So maybe you want to change a baseline. So one easy way to do that might be to change the random seed that we're using. So let's say you use an underscore random seed press Run. We might want to change the one invaluable be using. Now we're getting less notes and the baseline. You can remove this one a1 altogether. So now we're play every note. We can introduce a different kettle, different snare. There we go. And we can keep on making change as the, as the music is playing outline. So you can really see how you can use Live loops and sinking between live loops to make sure everything stays in time with each other. And just be able to change your code as you wish, as the performance is going on. 48. MIDI in: Okay, So as well as using code to play music, we can also take input in from a midi controller. So we need to set up a couple of things inside their preferences to enable this. So if we go over to the Preferences window here, if we go to I0, we can see here that we've got this enabled. So minus minus takes yours might be disabled here. So we need to make sure that we enable incoming cuz then you can see that I've got my my midi keyboard enabled here. So let's close that. And we'll see that. This is another instance where the, the cues panel can be particularly useful. So for example, if I press a note on my keyboard now, you'll see that logged in here is the name of the controller. And it's telling us that my archery or key step 37, which is the name of my midi controller. There was a note off, a note on event, followed by a note off events. And what this is telling us is that the notes on was a note 60, which is a middle seat. This second part of this list here is saying 100s. That is the velocity with which I press that note, if I press it again, I'll get different velocity. So there we are. That was a 112. A different note will give me a different number. So this was a note 67, which was a G, And I hit that with a velocity of 115. So we can use this information that's coming in from our midi keyboard to play some music using perhaps a synthesizer or a sound that we've created inside Sonic Pi, but be able to play it on our keyboard. So this is how we go about doing that. So first of all, let's create a lively work. Just call this one midi example. That's fine. Let's end that. Then in here, I need to do a couple of things. So I need to create two variables so we can separate these variables. So these are the most of velocity and this is what we're going to get from this list that we see in the queue here. So this is the note number and the velocity. We're going to say that a sync this to a. Now we need to give it the name of the event that's happening. So in our case then, in quotes, we're going to say exactly as it's written in the queue panel. And here we are. So it's going to pick it up from the queue panel for us. But we're going to say middy, colon are shari'a key step 31371. And this is the note on the pen. So we want to say, when we get a note on, I want to use a synth. I'm going to use the piano. Piano. And I'm going to pass it the note that came in from the midi keyboard. And I'm going to pass that to the note parameter or the no option. I'm going to set the amplitude to be whatever the velocity was divided by 127. The reason for that is because the amplitude that comes from Midea is a value between 0127. But the amplitude parameter or the amplitude option within Sonic Pi is set as a value between usually between 01. So we're just going to take that, take that velocity that comes in divided by 127 and that'll give us a suitable amplitude for site Pi. So let's run that. And now by pressing notes on my keyboard, I'm able to play the piano synth from with inside of Sonic Pi. And again, if I'd added any filters, envelopes, and he kind of ADSR parameters, etc. They will be reflected as I, as I play my midi keyboard. However, if you've got a midi keyboard connected and you have just used this example, obviously replacing this part here with whatever your, your keyboard is called from the cues panel. You'll notice that there is a great deal of latency. Now this latency actually exists on purpose and we can remove it, but the latency exists. I can guarantee that when you press this button, there is exactly 2.5th between new pressing a key. And you can actually see that if you look in the accused panel, there's a 2.5th delay between when you press a key. And when they actually sounds out. Now, this, this latency is built into Sonic Pi on purpose. And it really helps with the timing because computers, depending on what else is going on on the computer, computers can run a very varying speeds. So in order to be able to have things sink and work in a steady rhythm is we want to in a piece of music normally, depending on what's happening on the computer, this 2.5th delay is introduced on purpose to be able to counter that. So it's really simple to remove that latency if we want to play in real time. And we do that by just a simple command. So we just say use underscore real time. Now when I press Run, the notice sounded immediately that I pressed the relevant key on my midi controller keyboard. So this is all well and good. And you may say, Well Steve, that's great, but I can already play a synthesizer. I've got what it might door, I've got a standalone synthesizer that I can use. But actually now we can apply some of the programming that we've learned to our, to our synthesizer as it gets some interesting results. So we could say something like this. So instead of using this synth, we could say, okay, well, when I press a note on my keyboard, just maybe notebook, but excuse me, something at random from a scale that's defined by the note that's passed in. And then just play me something and random on the major pentatonic scale. Depending on the note that I've chosen. Anywhere within three octaves. And set the, as we did before. Let's set the amplitude to the, to be the velocity that's passed in. So how hard or how fast we hit the keyboard divided by a 127. Don't worry, if you miss the amplitude setting off. You'll just play at the default amplitude of one no matter how hard you hit the key. So it worked perfectly fine. Without it, you'll lose the velocity sensitivity of your keyboard. So what's going to happen now is whatever I play a note is going to choose a note at the major pentatonic scale, somewhere in three octaves for the notes that I have pressed. So I'm going to press a middle C or S3. And so when I click Run here, every time I press this note, it's going to play me a note from the major pentatonic scale. You can see in the queue is here on the, on the, on the cues panel. I've just been pressing middle C 60 throughout. But it emits a different note. Somewhere within the major pentatonic scale, within three octaves of the note that I played. Now, it's a good example to be able to show you that perhaps we can achieve some useful things with code. But let's have a look at perhaps a more and more useful example. Let's just remove this. Play again. This time, we'll use a synth, so we'll use the fluxes. Well, we'll keep this code. This code is perfectly good. This is just saying, okay, this is just creating a live loop, is saying to use real time and to capture the notes and the velocity from the note on event from our keyboard. But this time we'll do something a little bit more interesting. So let's say every time I press a note, I want to play a timed pattern. So instead of just playing one note will play a series of notes. So let's again get the scale from the note. From the notes that we, that we received from the keyboard. And we'll use the minor pentatonic again. But this time we're going to reflect it. So we'll play the whole scale up and down. And because we use in play pattern timed, we need to tell it how long we want to pause between, between notes. So we'll set this to be very short. And then we'll again set the amplitude to be the velocity divided by one hundred and twenty seven. Twenty-seven. So let me just move this over a little bit so we can see the whole line. So as I play a note on my midi keyboard, it's going to play me the minor pentatonic scale, based on the note that I've pressed. And it's going to play it very fast all the way up and then back down again at the velocity that I pass in. So let's hear how that sounds. So you can see that I'm just pressing in OneNote. We play in that whole pentatonic scale all the way up and all the way back down again. And of course I can add another object to this so I could say octaves. Very good. So you can see that we can really write some code that is triggered when we press a note on our midi keyboard to do a whole range of different things. And people have used this to really great effect joined by performances, particularly with different types of midi controllers, to be able to trigger different functions based on the note that's played in. So if you have a midi controller, whether it's a keyboard or whether it's a PAD, have a play around is quite easy to set up as we saw inside of Sonic Pi. And again, there's more help for you available in the Help panel around setting this up. But it's really quite simple to do. And it's a really, really powerful live performance device. So not only do have the ability to change code live within Live loops as you perform. But also you can use a midi controller to add some different dynamics to your live performance. 49. MIDI out: Okay, so that covers how we get into Sonic Pi. But Sonic Pi can also emit muddy. So we can control other midi devices or send midi to our DAW from our code. So to demonstrate this, I'm going to use a synthesized as a fantastic free synthesizer called vital. It's a synthesizer that I use on my complete beginners guide to synthesis and sound design course. So if you want to learn more about vital, please do go have a look at that course. I'm just going to load up a preset that I created the other day called the Skynet quiet. So this is what that sounds like. Okay, so that's synthesized running and I can play with my midi keyboard, but I can also play it using code. So I can see that in the preferences that I have a connected output, which is my archery a key step 37. Now, this is not something I can figure out. This is something that Sonic Pi was able to pick up as it opened based on the, the devices that I had connected to my computer. So I can set my default midi output channel. I just leave that set to all and we can control which channel we can use encode. And this can be useful if you're using something like contact where you could have multiple instruments running at once and send different commands out to different Midi channels to be able to control different contact instruments, for example. But we'll keep it nice and simple. We use vital. So let's write a little bit of code. So all we need to do is use the command midi, midi note on to start the midi note playing or to send a midi note on command to midi output device, our keyboard in this case. And then go off to say, okay, now really subtle. So let's, let's run a little bit code so we can say midi note on. There we go. So we can say emitting light on. Let's play an E three. It actually doesn't matter whether use a lowercase or an uppercase here. But I'm just using applications to keep it consistent throughout. We can say, then we're playing E3 and we will play it at a velocity of 50. And we will send this out to midi channel one. We're then going to sleep for four beats. And then we'll send the midi note off command, midi note off. And again, we'll need to say which note to switch off. So we're going to switch off the E3 that we just sent. And again, this is gonna be a command that we're going to send on channel number one. Let's, let's run that. And you can hear that coming out the synthesizer. Now if I run that again, you can see actually the bottom of the center I bought my vital. You can see on the keyboard midi note actually been sent. So it'd been sent through my midi controller. And backups are vital. As I said, with different virtual instruments, you could certainly and I have controlled contact directly from within Sonic Pi based on the midi channels that I send it. However, I've just choose, chosen to use vital in this instance because it's a fantastic and free synthesiser so everybody can follow along. So let's add another note as well. So let's send a midi note. On. This time we're going to send it an A4. And again, we'll use a velocity of 50 and we'll send it on channel one. Will sleep for. And then we'll suddenly really know off. And we'll tell it to switch off no, a4 on channel one. And let's press Play and then, or rum and then flick over to vital. There we go. So a fairly simple example, but it does demonstrate how you can send midi out of Sonic Pi and into whatever instrument or virtual instruments you want to connect to. And it's certainly one great use for this might be to control and an external analogue synth. So you might want to connect this to some sort of external synthesizers that you've got out from your computer through a midi cable and then send midi commands out of Sonic Pi to control whatever. Since that you might have. 50. Live audio: Okay, and there's one more way that we can enhance our live performances with Sonic Pi, and that is through the use of audio. So we can actually take audio in from a microphone or an external instrument like a guitar, and actually access that through Sonic Pi. And we can apply a bunch of effects and write code around the input that we get. To set that up, you need to go to Preferences. Go to the audio section, make sure that you have enabled audio inputs here. So in this panel down the bottom here, if it is disabled, just click that to enable the audio inputs. So Sonic Pi can take audio input from a number of different places. So it could take it from the microphone on your computer by default. It can take it from an external sound card or an audio interface. And if like me, you have an audio interface with multiple channels on it, then Sonic Pi is going to take the audio input from the first channel on your audio interface into the first channel on the audio interface that I have, I have plugged in my guitar to play that through Sonic Pi, I simply need to use the live audio commands. So I can just say live underscore audio and I need to give this live audio and name. So I'm going to call it a guitar. And now with this command when I press Run, you should now be able to hear the guitar coming through, through Sonic Pi. Then we are, we can see over in the scope and the top right here, we can see the spectrum analysis of the audio input. So let's press stop there for now. And as I said, this doesn't need to be guitar, could be a base, could be a keyboard, could be a microphone, etc. The exciting thing is it enables us to add effects, for example. So we can just wrap this with an effects loop. So let's say with underscore effects, Let's add a reverb. So now when I, when I run this, I should have my guitar sound as I did before, but with some reverb, I can add some distortion press Run. And of course I can next these effects as it did before, but as I said earlier, just be cautious with this. If you start adding too many effects, you will find that you start to suffer with a bit of performance, with some performance issues. So, but we can add a reverb, for example, on the outside of here, and we need another end loop. Let's format that and run that. And now I should have a distorted guitar with revert. Okay, let's get some really interesting by performance possibility. Flick over into this buffer rather than typing this all in. I've, I've, I've saved this into a different buffer and I'll talk you through the code. So at the top here I've got exactly the same as we had in the last section. So just the live audio coming in from the guitar through my audio interface and just applying some distortion and some reverb so that we then set the BPM to 96. Just for this example. We've then got a live loop which is playing a drum sequence in a very similar way to what we've seen before in previous sections. So just using this drum pattern here that we've described in these strings to play our three drum samples. We then got a loop, another live loop going on, which is just playing a bass part. So this is using a cynical base foundation, and it is just looping 16 times and choosing a note from the minor pentatonic scale or the E minor pentatonic scale, choosing a random row for that and it's playing one note every half a beat. And then we've got another library, which is called keys. And this is using the piano synth. And again, it's choosing from the E minor pentatonic scale, but three octaves above this one or two authors mother on, and it is playing a note every quarter of a beat and that's going round 16 note loop. Then on top of that, because we have the live audio, I can play input through my audio interface. On top of the sound is being produced with Sonic Pi. And I can actually record this out to a audio file with Sonic Pi playing my code in the background. And then with the lipids are on top by pressing the Record button here. And then pressing Run. And then stop the recording. And it lasts me where I want to save this file too. So I can save this to my desktop, for example, audio. Click save. And then over on my desktop, the file has been output as a WAV file. And I can listen to that through the Mac audio player. 51. Wrapping up: Okay, so that's it for this course. We've seen some of the fantastic possibilities are opened up when you use Sonic Pi to write code to create music. But there are about 250 different separate commands in Sonic Pi me, we've only really just scratched the surface. So look in the lung section of the, of the health panel and really have a dig around in there. All the commands have got really great documentation. On that note. I'd like to encourage you to look in the examples panels. So if you look in the health panel, look under examples and you'll see some really great examples that have been provided with Sonic Pi. I would certainly encourage you to have a look at some of those and dig through that code and really read through it and understand it. I can recommend a good, one. Good place to start might be something like Tilburg two, which is one of the examples in there. You simply click on the example in the health panel and then you can copy and paste the code out into one of the buffers in the code window in inside, inside Sonic Pi, you can play it and make changes to it and really experiment. Remember, there's no mistakes. You can't break anything by, by experimented inside Sonic Pi. And who knows some of these experiments might turn into your next great musical idea, your next great musical output. So it's a really great way for just experimented and discovering new music. Just don't forget to save your work regularly. As I said, Sonic Pi, we'll store it inside the buffer when you reload it. But, but just to be sure, I always like to when I'm really particularly happy with something, take a separate copy and save at ways of separate file. And there's always the undo button. If you do, if you do experiment and you go along the path you don't particularly like, then you can always undo your way out or revert to a previous safe states. But that really is it. So have some fun and I really encourage you to try some live performing, even if it's just yourself in your room performing a log, maybe in front of some families and friends, or when you get really good at it, go ahead, stage, go and show off what you've got. Have a look for algo rave. So just a few Google algorithm will send you to the algorithm website and you can see where some other people who've perhaps in your area or putting on some live performances. It just takes a bit of practice. This is the same as any other instrument. And so I really encourage you to spend your time each day the same as you would if you were learning the guitar or the piano, the harp, or any other instruments, just spend your time, a little bit of time each day practicing Sonic Pi, practicing a live performance, trying out different bits of code and different experiments, that little bit of practice each day we'll get you proficient in no time at all. I'm sure. Be shorter you to share your code and your music with the rest of the world, either through the community on the Sonic Pi website or however else you feel free, you feel comfortable to do so. I love to hear from you again, so please do share your code with me. Do share it on this website. If you'd like to learn more about some of the other courses and the other things I've got going on. Then please do head over to Steve live with music.com and you'll find out everything you need to know that it's been fantastic to have you Thank you so much for watching and I'll see you again soon.