My first Sonic PI song, well .... tryout after reading the tutorial

Slight warning: watch your speakers with this one…

Hope someone likes it, kinda …

#  __________________________________________________________________________________
# -= Swooosh Del1ght by Aurolis - My first Sonic PI Track, sortof ... a ... track ? =-
#  ----------------------------------------------------------------------------------

use_synth :tb303
use_bpm 68
B=0.5

#Cutoff knobby. Knobby who?
cutoff_facts=ring(0.6,0.7,0.8,0.9,0.8,0.7,0.6)

#Melody length =)
stretchy=(B+B/4+B/2+B/2+B/4+B/2)

#Dunno if there is a max function? There is now =)
define :threshold_cut do |n|
  return n <= 130 ? n : 130
end

define :piper do |f|
  with_fx :slicer, pulse_width: 0.4, probability: 1, amp:2 do
    sample :loop_amen, beat_stretch: stretchy/f
  end
end

define :m1 do |offset=0|
  cur_cut=cutoff_facts.tick
  play :C2+offset, cutoff: threshold_cut(80*cur_cut), release: 0.2, decay: 0.2
  
  sleep B
  play :Bb2+offset, cutoff: threshold_cut(90*cur_cut), release: 0.2
  
  sleep B/4
  play :C2+offset, cutoff: threshold_cut(80*cur_cut), release: 0.2, decay: 0.1
  
  sleep B/2
  play :Bb1+offset, cutoff: threshold_cut(70*cur_cut), release: 0.2
  
  sleep B/2
  play :C2+offset, cutoff: threshold_cut(90*cur_cut), release: 0.2
  
  sleep B/4
  play :Bb3+offset, cutoff: threshold_cut(90*cur_cut), release: 0.3
  
  sleep B/2
end

define :m2 do |offset=0, end_note=true|
  cur_cut=cutoff_facts.tick
  
  play :C2+offset, cutoff: threshold_cut(80*cur_cut), release: 0.2
  
  sleep B/4
  play :D2+offset, cutoff: threshold_cut(80*cur_cut), release: 0.1
  
  sleep B/4
  play :Eb2+offset, cutoff: threshold_cut(90*cur_cut), release: 0.2
  
  sleep B/4
  play :G2+offset, cutoff: threshold_cut(90*cur_cut), release: 0.1
  
  sleep B/4
  play :G3+offset, cutoff: threshold_cut(90*cur_cut), release: 0.2
  
  sleep B/4
  play :C3+offset, cutoff: threshold_cut(90*cur_cut), release: 0.1
  
  sleep B/4
  play :D3+offset, cutoff: threshold_cut(90*cur_cut), release: 0.2
  
  sleep B/4
  play :Eb3+offset, cutoff: threshold_cut(90*cur_cut), release: 0.1
  
  sleep B/4
  play :G4+offset, cutoff: threshold_cut(90*cur_cut), release: 0.2
  
  sleep B/4
  play :G5+offset, cutoff: threshold_cut(90*cur_cut), release: 0.1
  
  sleep B/4
  play :C4+offset, cutoff: threshold_cut(90*cur_cut), release: 0.2
  
  sleep B/4
  play :D4+offset, cutoff: threshold_cut(90*cur_cut), release: 0.1
  
  sleep B/4
  if end_note
    play :Eb5+offset, cutoff: threshold_cut(110*cur_cut), release: 0.2, decay: 0.8
  end
  
end

define :m1_fx do |cnt,offset=0|
  cnt.times do
    sample :loop_amen,beat_stretch: stretchy
    with_fx :bpf,mix: 0.1 do
      m1(offset)
    end
  end
end

define :proceed do |offset=0,end_note=true|
  sample :loop_amen,beat_stretch: stretchy
  with_fx :bpf,mix: 0.1 do
    m2(offset,end_note)
  end
end

define :p1 do |cnt|
  cnt.times do
    m1_fx(2)
    piper(4)
    m1_fx(2)
    piper(8)
    m1_fx(2)
    piper(2)
    m1_fx(1)
    proceed
  end
end

define :p2 do |cnt|
  cnt.times do
    play :Eb5, cutoff: threshold_cut(80), release: 0.2, decay: 0.5
    m1_fx(1)
    play :D5, cutoff: threshold_cut(80), release: 0.2, decay: 0.3
    m1_fx(1)
    play :C5, cutoff: threshold_cut(80), release: 0.2, decay: 0.3
    m1_fx(2)
  end
end

define :p3 do |cnt|
  cnt.times do
    
    2.times do
      play :Eb5, cutoff: threshold_cut(80), release: 0.2, decay: 0.5
      m1_fx(1,5)
      play :D5, cutoff: threshold_cut(80), release: 0.2, decay: 0.3
      m1_fx(1,5)
      play :C5, cutoff: threshold_cut(80), release: 0.2, decay: 0.3
      m1_fx(2,5)
      
      play :Eb6, cutoff: threshold_cut(80), release: 0.3, decay: 0.5
      m1_fx(1,10)
      play :D6, cutoff: threshold_cut(80), release: 0.4, decay: 0.3
      m1_fx(1,10)
      play :C6, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
      m1_fx(2,10)
      
      play :D5, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
      m1_fx(1)
      play :Bb4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
      m1_fx(1)
      play :C5, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
      m1_fx(1,5)
      play :Eb5, cutoff: threshold_cut(80), release: 0.2, decay: 0.5
      m1_fx(1,5)
      
      play :G4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
      play :Bb4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
      play :D4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
      
      m1_fx(2)
      
      play :F4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
      play :A4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
      play :C3, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
      
      m1_fx(2)
      
      play :Eb4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
      play :G4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
      play :Bb4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
      
      m1_fx(2,5)
      
      play :F4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
      play :A4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
      play :C5, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
      
      m1_fx(2,5)
      
    end
    
    play :D3, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    play :F4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    play :Bb4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    
    m1_fx(2,10)
    
    play :D3, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    play :Gb4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    play :Bb4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    
    m1_fx(2,10)
    
    play :Eb4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    play :G4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    play :Bb4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    
    m1_fx(2)
    
    play :F4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    play :A4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    play :C5, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    
    m1_fx(2,5)
    
    
    play :D3, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    play :F4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    play :Bb4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    
    m1_fx(2,19)
    
    play :D3, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    play :F4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    play :Bb4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    
    m1_fx(2,5)
    
    play :D3, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    play :F4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    play :Bb4, cutoff: threshold_cut(80), release: 0.5, decay: 0.3
    
    m1_fx(3,10)
    
    proceed(10,true)
    
  end
end

with_fx :reverb,room: 1 do
  p1(2)
  p2(2)
  p1(1)
  p2(1)
  p3(1)
end

cutoff_facts=ring(0.4,0.5,0.6,0.4,0.6,0.4,0.5)
with_fx :reverb,room: 1, damp: 0 do
  with_fx :bitcrusher, bits:8, cutoff: 110 do
    p3(1)
  end
end
4 Likes

Hi Aurolis,

Thank you so very very much… this is hard to explain, butI I havent been able to post
for the last few weeks, because all the discussions have been very technical, about
deep things about Markov chains, and … well, other things.

But this is simple SP code that I can react to, and it’s also what I would call ‘hardcore
house’… (others opinions might vary).

So, thanks again, and I’m lovin it… ‘Respec’… :slight_smile:

Eli…

1 Like

Thank you for your very nice response, I really appreciate it =)

If you have some free time on Friday and Saturday evenings, this is a bunch of hardcore house DJ’s,
who currently cant play gigs… so we’ve set up our own stream playing mostly vinyl.

We also play dub, and dub-hardcore… so, I dunno, you might get idea’s for your next track from
some classics?

Eli…

Good stuff! Excited to hear more of your work! :smiley:

1 Like

Excellent! I find it very rich, in terms of rhytm, harmonies and sound. You can run it for many minutes and still it produces new aspects.

In the code you are asking Dunno if there is a max/min function? Here it is:

[th, 130].min
[th, 20].max

Whatever the value of th is, the first line ensures that you won’t get more than 130, the second line always gives you at least 20.

2 Likes

Hi Eli, I know it is difficult for non-mathematically-minded people to follow the discussion. Therefore, a short explanation here: Think of a Markov chain just as a tool to randomly generate sequences of chords or notes. And what is the difference to the usual [...].choose or [...].pick? Well, the choice depends on the previous chord/note being played right now. This way, you can make an :D3 following a :C3 more likely than using just [:C3, :D3, ..., :B3].choose. That’s basically all you need to know. :wink:

Thank you :slight_smile:
To be honest, I am more into blues, but I like to experiment with computerized music, but mostly I listen to blues :slight_smile:

Thank you very much for your kind words and also for you taking the time to actually read the code and the comments! Thanks for the min/max tip, another thing learned :wink:

Thank you very much, I hope I can bring you and the others more stuff =)

1 Like

I very much like blues to play along with the guitar. Therefore I created some pieces with Sonic Pi that play the blues but without the voice (see for example here)

Really cool track! :+1: I particularly like the slow organ-like melody. I would tend to call it high-speed drum and bass (due to the amen break).

1 Like

Thank you :slight_smile:

That is cool!! Man, Sonic PI is really cool! I was not aware that it was this cool! Only thing I really miss is a better performance, so … I guess someone could really rewrite this in C++, or … better yet: Rust

I am still going through the tutorial, learning a lot and getting some ideas. The way the tutorial is written also clear illustrates that Sam is an awesome creative dude, focussing on having fun, i love it =)

What is your problem with Sonic Pi’s performance? So far (on a laptop), I did not scratch the limits. But I am also fairly new to it. Actually, most of Sonic Pi is written in C++.

Being a big fan of Rust too, its use would definitely lower the barrier to contribute for me. IIRC correctly, in a talk or interview Sam mentioned to indeed plan to rewrite a certain part in Rust. But not really sure here…

Well, I noticed with a BPM of 60 for instance, I can’t have a sleep below 0.1 driven correctly in a loop, so I wanted to create a fast drumroll for instance and that doesn’t work. I need to create a sample for that :frowning:
But then again, I am very impressed by the thread system, I love that!
I run it on a laptop, but maybe my laptop is just slow…

Try this:

use_debug false
live_loop :fast, auto_cue: false do
  density 10 do
    play :e4, release: 0.1
    sleep 1
  end
end

Disable the debug output and change the time scale using density

1 Like

Nechoj is right…

Density is a very very good way of writing ‘drops’… you simply
change the density on the beat, maybe change the amp, and it
powers up to the drop, then you flip amp to 0, pull in an ethereal sample,
then put density back to 1, and carry on the track…

Eli…

Like that?

use_debug false
live_loop :fast, auto_cue: false do
  
  tick_reset
  density 16 do
    sample :drum_snare_hard, amp: (range 0.1, 1.8, 0.1).tick
    sleep 2
  end
  
  sleep 0.25
  sample :drum_snare_hard, amp: 0.8
  sleep 0.125
  sample :drum_cymbal_open
  sample :guit_em9
  sleep 4
end

(I am not so good at ethereal things …)

Wow, that is an awesome trick! Thank you very much Jochen! :slight_smile: