# Salutations! (A Journey into Sonic Pi and MIDI)

**URL:** <https://in-thread.sonic-pi.net/t/salutations-a-journey-into-sonic-pi-and-midi/2203>\
**Category:** Introductions & Stories\
**Created:** [April 4, 2019, 5:30am UTC](https://in-thread.sonic-pi.net/t/salutations-a-journey-into-sonic-pi-and-midi/2203 "2019-04-04T05:30:13Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![M\_Rollers](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/m_rollers/32/912_2.png) [@M\_Rollers](https://in-thread.sonic-pi.net/u/M_Rollers)\
**Post date:** [April 4, 2019, 5:30am UTC](https://in-thread.sonic-pi.net/t/salutations-a-journey-into-sonic-pi-and-midi/2203/1 "2019-04-04T05:30:13Z")

</div>

My name is Allen and I live outside of Memphis, TN. I’ve been working on electronic music since the early…never mind. I’m a complete coding noob. Last Tuesday a friend of mine posted an article from CDM about Live Coding. I did some searching and watched several of Sam’s presentations on youtube. I was impressed with how things seemed to work and all the possibilities. Also there seemed to be a diy spirit to everything. My only question was, “Can I live code this table of hardware?”.

A week later and the answer is yes and I’m loving it!

Last night I learned functions and they seem super powerful. Here is what I did for the Arturia Drumbrute.

```ruby
#Drumbrute Functions
define :dbk1 do midi_note_on 36, release: 1,channel:10 ,port:"akai_eie_pro_midi" end
define :dbk2 do midi_note_on 37, release: 1,channel:10 ,port:"akai_eie_pro_midi" end
define :dbsn do midi_note_on 38, release: 1,channel:10 ,port:"akai_eie_pro_midi" end
define :dbclp do midi_note_on 39, release: 1,channel:10 ,port:"akai_eie_pro_midi" end
define :dbrim do midi_note_on 40, release: 1,channel:10 ,port:"akai_eie_pro_midi" end
define :dbclav do midi_note_on 41, release: 1,channel:10 ,port:"akai_eie_pro_midi" end
define :dbohat do midi_note_on 42, release: 1,channel:10 ,port:"akai_eie_pro_midi" end
define :dbchat do midi_note_on 43, release: 1,channel:10 ,port:"akai_eie_pro_midi" end
define :dbconghi do midi_note_on 44, release: 1,channel:10 ,port:"akai_eie_pro_midi" end
define :dbtomhi do midi_note_on 45, release: 1,channel:10 ,port:"akai_eie_pro_midi" end
define :dbconglo do midi_note_on 46, release: 1,channel:10 ,port:"akai_eie_pro_midi" end
define :dbtomlo do midi_note_on 47, release: 1,channel:10 ,port:"akai_eie_pro_midi" end
define :dbcym do midi_note_on 48, release: 1,channel:10 ,port:"akai_eie_pro_midi" end
define :dbrev do midi_note_on 49, release: 1,channel:10 ,port:"akai_eie_pro_midi" end
define :dbmara do midi_note_on 50, release: 1,channel:10 ,port:"akai_eie_pro_midi" end
define :dbtam do midi_note_on 51, release: 1,channel:10 ,port:"akai_eie_pro_midi" end
define :dbzap do midi_note_on 52, release: 1,channel:10 ,port:"akai_eie_pro_midi" end 

```

I would like to code something like this for my synths. I have some ideas. Variables for the midi channels/ports maybe? Less typing is good right?

---

<div class="post-metadata">

**Author:** ![Bubo](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/bubo/32/786_2.png) [@Bubo](https://in-thread.sonic-pi.net/u/Bubo)\
**Post date:** [April 4, 2019, 5:53am UTC](https://in-thread.sonic-pi.net/t/salutations-a-journey-into-sonic-pi-and-midi/2203/2 "2019-04-04T05:53:28Z")

</div>

That’s one way of doing it but I think that it would be more efficient to just give names to your midi notes and not to the whole package of informations.

Something like:

```
dbk1 = 36
dbk2 = 37

```

And then:

`midi (ring dbk1, dbk2).tick(:brute), release: [0.5, 1].choose, channel: 1`

This way, you have less things to type, and more possibilities to modulate your midi output. In your situation, the only crucial information you have in your function is the midi number to trigger the right sound. I don’t think that you need a function to store this information.

---

<div class="post-metadata">

**Author:** ![samaaron](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/samaaron/32/7_2.png) [@samaaron](https://in-thread.sonic-pi.net/u/samaaron)\
**Post date:** [April 4, 2019, 10:29am UTC](https://in-thread.sonic-pi.net/t/salutations-a-journey-into-sonic-pi-and-midi/2203/3 "2019-04-04T10:29:56Z")

</div>

Hey @M_Rollers,

A warm welcome to you - thanks for joining our community. Great to hear that you’re starting your journey experimenting with controlling your external synths with algorithms and code. Please do continue to share your thoughts and ideas with us - you have no idea how many people you’ll end up inspiring!

Looking forward to hearing some of your coded beats!

---

<div class="post-metadata">

**Author:** ![darinwilson](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/darinwilson/32/798_2.png) [@darinwilson](https://in-thread.sonic-pi.net/u/darinwilson)\
**Post date:** [April 4, 2019, 2:08pm UTC](https://in-thread.sonic-pi.net/t/salutations-a-journey-into-sonic-pi-and-midi/2203/4 "2019-04-04T14:08:19Z")

</div>

Hi @M_Rollers - welcome!

I agree that less typing is good - especially in live situations. And functions are indeed super powerful. One thing that they’re great for is reducing repetition. And since functions can call other functions, one suggestion I might have is to create a separate `:brute` function that handles all of the values that are the same, and accepts the midi note as a parameter.

Maybe something like this:

```ruby
define :brute do |midi_note|
  midi_note_on midi_note, release: 1, channel:10, port:"akai_eie_pro_midi"
end

define :dbk1 do brute 36 end
define :dbk2 do brute 37 end
define :dbsn do brute 38 end
# etc...

```

This way, if you ever want to change the release, channel, or port, you just have to do it in one place. Less typing! 😃

I hope that answers your question, and if not, please let us know. Have fun, and please post some recordings of what you’re up to!

---

<div class="post-metadata">

**Author:** ![M\_Rollers](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/m_rollers/32/912_2.png) [@M\_Rollers](https://in-thread.sonic-pi.net/u/M_Rollers)\
**Post date:** [April 4, 2019, 3:14pm UTC](https://in-thread.sonic-pi.net/t/salutations-a-journey-into-sonic-pi-and-midi/2203/5 "2019-04-04T15:14:49Z")

</div>

Thanks for your response. I chose functions because from my understanding, you can load at the beginning of a session, then erase and your functions still work. I’m sure my code will evolve over time and I will make tweaks to make it more efficient. I love seeing people ideas, it can really give a fresh perspective. As it is now my Drumbrute sequencing is looking like this.

```ruby
use_bpm 120

live_loop :db1 do
  dbk2
  sleep 0.5
  dbchat
  sleep 0.5
  dbk2
  #dbclp
  sleep 0.5
  dbchat
  sleep 0.5
end
live_loop :db2 do
  sleep 1.25
  dbtomlo
  sleep 0.25
  dbrev
end
live_loop :db3 do
  sleep 0.75
  dbmara
  sleep 0.125
  dbmara
  sleep 0.005
  dbclav
  sleep 1
end
live_loop :db4 do
  dbcym
  sleep 0.25
end

```

---

<div class="post-metadata">

**Author:** ![M\_Rollers](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/m_rollers/32/912_2.png) [@M\_Rollers](https://in-thread.sonic-pi.net/u/M_Rollers)\
**Post date:** [April 4, 2019, 3:45pm UTC](https://in-thread.sonic-pi.net/t/salutations-a-journey-into-sonic-pi-and-midi/2203/6 "2019-04-04T15:45:22Z")

</div>

THIS is the sort of thing I definitely need to set up with the synths! The thing about MIDI is it doesn’t always work the same. Case in point, Behringer Model D and Neutron. They both are a bit ticky to trigger with midi, the midi note has to be a certain length for the ADSR(or ADS on Model D) to work right. This is the case with my Zaquencer, Renoise, Ableton, etc. My Yamaha CS5 with Kenton Pro Solo mkii works perfect and as expected. I guess you get what you pay for. I like the Behringers and think they sound great for the price, but they have some quirks. More on this later. I think I got my ASIO working with Sonic Pi so maybe I can get to recording soon. If not I may can record my audio into Live.

---

<div class="post-metadata">

**Author:** ![darinwilson](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/darinwilson/32/798_2.png) [@darinwilson](https://in-thread.sonic-pi.net/u/darinwilson)\
**Post date:** [April 4, 2019, 9:05pm UTC](https://in-thread.sonic-pi.net/t/salutations-a-journey-into-sonic-pi-and-midi/2203/7 "2019-04-04T21:05:40Z")

</div>

I’ve been having a lot of fun working with Sonic Pi and Ableton. So far, I’ve just been using Ableton as a host for AU plugins, and using the midi out in Sonic Pi to play through the plugins. It’s nice to be able to use Sonic Pi as the coding environment, but still be able to use any sound source.

It’s super cool that you’re using it to drive hardware!

---

<div class="post-metadata">

**Author:** ![Bubo](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/bubo/32/786_2.png) [@Bubo](https://in-thread.sonic-pi.net/u/Bubo)\
**Post date:** [April 5, 2019, 12:11am UTC](https://in-thread.sonic-pi.net/t/salutations-a-journey-into-sonic-pi-and-midi/2203/8 "2019-04-05T00:11:42Z")

</div>

@M_Rollers: if you want your code to be optimal and without repetition, I really think that you should aim at writing every instruction only once. I still think that wrapping parameters inside a function is not always a good idea because it makes you jump in your code too often. I do prefer using a dense writing style that helps me moving fast when I improvise.

Here is an example. You posted the following code:

```
 live_loop :db1 do
  dbk2
  sleep 0.5
  dbchat
  sleep 0.5
  dbk2
  #dbclp
  sleep 0.5
  dbchat
  sleep 0.5
end

```

Here is how I would have written it:

```
live_loop :db1 do ; tick ; use_bpm 120
midi (ring dkb2, dbchat, dbk2, dbchat).look, release: 1, channel: 1
sleep (ring 0.5).look 
end

```

I think that this gives you the opportunity of making changes really fast. For instance, I only have to add a comma and another number to create rhythmic variation. I just have to write something like `[0.5, 1].choose` to play with the release time, etc…

---

<div class="post-metadata">

**Author:** ![M\_Rollers](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/m_rollers/32/912_2.png) [@M\_Rollers](https://in-thread.sonic-pi.net/u/M_Rollers)\
**Post date:** [April 5, 2019, 2:57am UTC](https://in-thread.sonic-pi.net/t/salutations-a-journey-into-sonic-pi-and-midi/2203/9 "2019-04-05T02:57:09Z")

</div>

What do you mean by “jump in your code”? I tried your code, it doesn’t sound the same at all. The timing is all off. Mine alternates kick and hat, yours plays kick and hat at the same time. Are you calculating the release time in? Honestly I can take it out of my code completely, because it has no effect on the Drumbrute.

---

<div class="post-metadata">

**Author:** ![Bubo](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/bubo/32/786_2.png) [@Bubo](https://in-thread.sonic-pi.net/u/Bubo)\
**Post date:** [April 5, 2019, 4:42am UTC](https://in-thread.sonic-pi.net/t/salutations-a-journey-into-sonic-pi-and-midi/2203/10 "2019-04-05T04:42:11Z")

</div>

Maybe there is some hardware specifics that I don’t know about. You may need to have the release time to be equal or superior to 1. However, this doesn’t mean that my example is wrong. I was just not aware that the DrumBrute was meant to be used with this amount of release. For instance, check the following code:

```
live_loop :db1 do ; tick ; use_bpm 120
  sample (ring :drum_bass_soft, :drum_cymbal_closed, :drum_snare_soft, :drum_cymbal_closed, :drum_bass_soft,
          :drum_cymbal_closed, :drum_snare_soft, :drum_cymbal_closed).look, release: 1, channel: 1
  sleep (ring 0.5).look
end

```

I’ve replaced the `midi` operator with the `sample` one so we can be sure that we will hear the same thing. You will hear a steady beat, without tempo fluctuation or overlapping sounds.

EDIT: Of course, in my old example, I was still talking about having dkb1, dkb2 and all these things being declared as follow:

```
dbk1 = 36
dbk2 = 37
```

---

<div class="post-metadata">

**Author:** ![M\_Rollers](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/m_rollers/32/912_2.png) [@M\_Rollers](https://in-thread.sonic-pi.net/u/M_Rollers)\
**Post date:** [April 5, 2019, 3:14pm UTC](https://in-thread.sonic-pi.net/t/salutations-a-journey-into-sonic-pi-and-midi/2203/11 "2019-04-05T15:14:58Z")

</div>

Cool. I was able to reformat your last code a bit and it worked on the drumbrute. I went ahead and did the other parts as well(except the last one). Just used Midi note numbers to get it working. Do I need the .tick and use\_bpm for each live\_loop?

```ruby
live_loop :db1 do ; tick ; use_bpm 120
  midi_note_on (ring 37,43,39,43).look,channel:10 ,port:"akai_eie_pro_midi"
  sleep (ring 0.5).look
end
live_loop :db2 do ; tick ; use_bpm 120
  midi_note_on (ring 47,49).look,channel:10 ,port:"akai_eie_pro_midi"
  sleep (ring 1.75,0.25).look
end
live_loop :db3 do ; tick ; use_bpm 120
  midi_note_on (ring 50,50,41).look,channel:10 ,port:"akai_eie_pro_midi"
  sleep (ring 1.75,0.125,1).look
end
live_loop :db4 do tick ; use_bpm 120
  dbcym
  sleep 0.25
end

```

---

<div class="post-metadata">

**Author:** ![Bubo](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/bubo/32/786_2.png) [@Bubo](https://in-thread.sonic-pi.net/u/Bubo)\
**Post date:** [April 5, 2019, 4:11pm UTC](https://in-thread.sonic-pi.net/t/salutations-a-journey-into-sonic-pi-and-midi/2203/12 "2019-04-05T16:11:46Z")

</div>

`Tick` and `Look` are very strange things. Think about them like counters that are counting nothing. They just tell Sonic-Pi to read the next value stored in a `ring` or an array.

These things can have names if you want multiple instances of this counter:

`tick(:one) ; tick(:two) ; tick(:three)`

I guess that this is because sometimes it is cool to be able to have conditionnal counters and stuff like that for generating complex patterns.

> [@M\_Rollers](#):
>
> Do I need the .tick and use\_bpm for each live\_loop?

I guess you can stick to it for the moment. `Tick` will be your unnamed counter for each loop, and `use_bpm` can be modified if you want one pattern to be faster than the other. It can be a fun effect. Something like `use_bpm 120` VS `use_bpm 60` or 240.

---

<div class="post-metadata">

**Author:** ![M\_Rollers](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/m_rollers/32/912_2.png) [@M\_Rollers](https://in-thread.sonic-pi.net/u/M_Rollers)\
**Post date:** [April 5, 2019, 6:16pm UTC](https://in-thread.sonic-pi.net/t/salutations-a-journey-into-sonic-pi-and-midi/2203/13 "2019-04-05T18:16:08Z")

</div>

Thank you for your help. This is a lot to process. I have used the .tick to make arpeggios with a chord, the look is new to me. The more I understand how the code is working, the easier it will be.

---

<div class="post-metadata">

**Author:** ![Bubo](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/bubo/32/786_2.png) [@Bubo](https://in-thread.sonic-pi.net/u/Bubo)\
**Post date:** [April 5, 2019, 6:23pm UTC](https://in-thread.sonic-pi.net/t/salutations-a-journey-into-sonic-pi-and-midi/2203/14 "2019-04-05T18:23:50Z")

</div>

Yes, you’ll see, it’s just some getting used to. After a while, you will not even be thinking about all that and it will be like a second nature. Once you feel confident using `rings` for easy and fast sequencing, try to learn the less obvious types of rings. There are a few of them that nobody is talking about, and some of them are great for MIDI\_CC controls and more precise, specialised sequencing (line, octave, bools, etc…) Here is a small repository of some examples taken from the tutorial / guide I wrote earlier about this topic:

BOOLEAN DRUM MACHINE

```
live_loop :perc do ; tick
  sample :bd_boom, amp: 1 if bools(1, 0, 0, 1, 0).look
  sample :perc_snap2, amp: 1 if bools(1, 0, 1, 0).look
  sample :drum_cowbell, amp: 1 if bools(0, 0, 0, 1).look
  sample :drum_snare_hard, amp: 0.7 if bools(0, 0, 1, 0).look
  sleep 0.25
end

```

LINE AND PARAMETRICAL CHANGE SMOOTHING

```
live_loop :line do ; tick
  use_synth :noise
  play :c4, release: (line 0.001, 0.10, steps: 10).look
  sleep 0.125
end

```

EUCLIDIAN SEQUENCES

```
live_loop :euclidien do ; tick
  play :c3 if spread(1, 4).look
  play :g3 if spread(4.5, 10).look
  play :g4 if spread(4.5, 11).look
  play :g5, amp: 0.1 if spread(15, 32).look
  sleep 0.25
end

```

KNIT FOR REPEATING VALUES

```
live_loop :knit do ; tick
  play (knit :f4, 2, :g4, 2, :ab4, 2).look, release: 0.1
  play (knit :c5, 2, :bb4, 2, :f4, 2).look, release: 0.1
  sleep (knit 0.125, 16, 0.125/2, 2, 0.125, 16, 0.5, 1).look
end

```

And to give you even more control on these sequences, you can create combinations with the`.tick` method. For instance, you can do something like `.mirror.tick` or `.shuffle.tick`. Take your time with these things, but if you are playing with hardware machines, it will some good days of midi sequencing jams.

EDIT: And I guess that it’s 90% of what you need to know to master midi sequencing in SP.
