DJ Dumo, Jeeshan, MC Zanj - Let Go (Doffu Glitch)

I used Sonic Pi to glitch the heck out of a song my friends recently released. Bass, Lead Synth, FX and final arrangement done in Logic. Hope you enjoy!

Original song can be heard here so you can get an idea of how much things changed:

The code for this is mostly recycled from older compositions so thats why the naming in the code may be weird or why you may see some unused code chunks but I’ll post it for those interested anyways:

# INITIALIZE MASTER VALUES
use_bpm 102
counter0 = 0
use_random_seed 0 #14 #8 #3# Welcome to Sonic Pi v3.1

# LOAD IN SAMPLE LIBRARIES
barretA = "/Users/sheakennedy/Desktop/Elder Desktop/DESKTOP/Drum Kits _ Samples/Homebrew/Let Go Jeeshan A/"
barretDrum = "/Users/sheakennedy/Desktop/Elder Desktop/DESKTOP/Drum Kits _ Samples/Homebrew/Barret Drums/"
barretBreak = "/Users/sheakennedy/Desktop/Elder Desktop/DESKTOP/Drum Kits _ Samples/Homebrew/Polybius/"
barretB = "/Users/sheakennedy/Desktop/Elder Desktop/DESKTOP/Drum Kits _ Samples/Homebrew/Barret Loops/C"
barretC = "/Users/sheakennedy/Desktop/Elder Desktop/DESKTOP/Drum Kits _ Samples/Homebrew/B - Breaks/"
barretD = "/Users/sheakennedy/Desktop/Elder Desktop/DESKTOP/Drum Kits _ Samples/Homebrew/Barret Loops/D"
barretE = "/Users/sheakennedy/Desktop/Elder Desktop/DESKTOP/Drum Kits _ Samples/Homebrew/Barret Loops/E"
barretF = "/Users/sheakennedy/Desktop/Elder Desktop/DESKTOP/Drum Kits _ Samples/Homebrew/B - Breaks"
barretG = "/Users/sheakennedy/Desktop/Elder Desktop/DESKTOP/Drum Kits _ Samples/Homebrew/Side Quest Loops"
eckDrum = "/Users/sheakennedy/Desktop/Elder Desktop/DESKTOP/Drum Kits _ Samples/Sample Packs/Hip Hop Samples/Samples/"


# AUTOMATION
line_Riser0 = (line 10, 0, inclusive: true, steps: 16)
line_Riser1 = (line 8, 0, inclusive: true, steps: 128)
line_Riser2 = (line 4, 0, inclusive: true, steps: 128)
lfo0 = (line 70, 100, inclusive: true, steps: 16).mirror
lfo1 = (line 0.8, 0.99, inclusive: true, steps: 32).mirror
lfo2 = (line 120, 60, inclusive: true, steps: 4).mirror
lfo3 = (line 120, 100, inclusive: true, steps: 8)
lfo4 = (line 0.7, 0.99, inclusive: true, steps: 4).mirror
lfo5 = (line 0.3, 0.99, inclusive: true, steps: 2).mirror

# LEVELS
inst0_lvl           = 1 ##
inst1_lvl           = 1  #
inst2_lvl           = 1 ##
inst3_lvl           = 1
inst4_lvl           = 1
inst5_lvl           = 1
inst6_lvl           = 1
inst7_lvl           = 1
inst8_lvl           = 1
trap_lvl            = 1

# PART
part                = 0

live_loop :euclid_beat2 do
  if(inst0_lvl == 1)
    if part == 0
      with_fx :level, amp: inst0_lvl do
        puts tick
        n = 8
        s =  line(0, 1, steps: n).choose
        f = s + (1.0 / n)
        sample barretA, 14, rate: 0.5, beat_stretch: 2, start: s, finish: f, release: 0.01 #Break,8,-1
        sleep 4.0  / n
      end
    end
    if part == 1
      with_fx :level, amp: inst0_lvl do
        puts tick
        n = 8
        s =  line(0, 1, steps: n).choose
        f = s + (1.0 / n)
        sample barretA, 14, rate: 0.5, beat_stretch: 2, start: s, finish: f, release: 0.01 #Break,8,-1
        sleep 4.0  / n
      end
    end
  end
  if(inst0_lvl == 0)
    sleep 0.25
  end
end


live_loop :euclid_beat3 do
  if(inst1_lvl == 1)
    puts tick
    with_fx :level, amp: (ring 1,0,1,0,1,1,0,1).look do #choose([1,0]) do
      sample barretA, 13, rate: (ring 1,1,1,1,1,1,1,2).look, onset: (ring 0,4,1,433,0,5,13,7,  0,4,0,90,7,8,19,17).look, release: 0.01
    end
  end
  sleep 1
end

live_loop :trip2 do
  puts tick
  if(inst2_lvl == 1)
    if part == 0
      with_fx :level, amp: choose([1])  do
        sample barretA, 15, rate: (ring 4,1,2,1).look, onset: (ring 4,1,2,1,3,0,0,6).look, release: 0.01 if (spread 10, 16).look #barretD 3
      end
    end
    if part == 1
      with_fx :level, amp: choose([1])  do
        sample barretA, 13, rate: (ring 4,1,2,1).look, onset: (ring 4,1,2,0,3,0,0,6).look, release: 0.01 if (spread 8, 16).look
      end
    end
  end
  sleep (ring 0.25).look #Switch between these to change pacing
  #sleep (ring 0.25, 0.125, 0.125).look
end

live_loop :trip3 do
  puts tick
  if(inst3_lvl == 1)
    if part == 0
      with_fx :level, amp: choose([1])  do
        sample barretA, 11, rate: (ring 4,8,2,1).look, onset: (ring 4,1,2,1,3,0,0,6).look, release: 0.01 if (spread 14, 16).look
      end
    end
    if part == 1
      with_fx :level, amp: choose([1])  do
        sample barretA, 11, rate: (ring 4,8,2,1).look, onset: (ring 4,1,2,1,3,0,0,6,4,1,2,1,8,9,10,11).look, release: 0.01 if (spread 14, 16).look
        sample barretA, 14, rate: (ring 4,8,2,1).look, onset: (ring 4,1,2,1,3,0,0,6).look, release: 0.01 if (spread 7, 16).look
      end
    end
  end
  sleep (ring 0.5, 0.25, 0.25).look #Switch between these to change pacing
  #sleep (ring 0.25, 0.125, 0.125).look
end


live_loop :amen3 do
  if(inst4_lvl == 1)
    puts tick
    if part == 0
      with_fx :level, amp: choose([1,1])  do
        with_fx :distortion do
          sample barretB, 4, rate: choose([2,1]), onset: pick, sustain: 0, release: choose([0.1, 0.2])
        end
      end
    end
  end
  sleep 0.5
end

live_loop :amen4 do
  if(inst5_lvl == 1)
    puts tick
    with_fx :level, amp: choose([1,1])  do
      
      n = 2
      s =  line(0, 1, steps: n).choose
      f = s + (1.0 / n)
      sample barretA, 11, rate: 0.25, beat_stretch: 2, start: s, finish: f #Break,8,-1
      sleep 8.0  / n
      
    end
  end
  if(inst5_lvl == 0)
    sleep 0.25
  end
end

live_loop :amen5 do
  if(inst6_lvl == 1)
    puts tick
    if part == 0
      with_fx :level, amp: choose([1,1])  do
        sample barretA, 10, rate: (ring 4,1,2,1).look, onset: (ring 4,1,2,1,3,0,0,6,  4,1,1,1,1,47,4927,631).look, sustain: 0, release: choose([0.5])
      end
    end
    if part == 1
      with_fx :level, amp: choose([1,1])  do
        sample barretA, 10, rate: (ring 4,2,2,4).look, onset: (ring 4,1,2,1,3,0,0,6,  4,1,1,1,1,47,4927,631).look, sustain: 0, release: choose([0.5, 0.5])
        sleep choose([0,0.25])
      end
    end
  end
  sleep 0.5
end

live_loop :euclid_beatX do
  if(inst7_lvl == 1)
    puts tick
    sample eckDrum, 39, rate: (ring 1).look, sustain: 0, release: choose([1])
    sleep 0.5
    with_fx :slicer do
      sample eckDrum, 11, rate: (ring 1).look, sustain: 0, release: choose([1])
    end
  end
  sleep 0.5
end

live_loop :euclid_beatY do
  if(inst8_lvl == 1)
    puts tick
    with_fx :flanger do
      sample eckDrum, 59, rate: (ring 0.5).look, sustain: 0, release: choose([0.01])
    end
  end
  sleep (ring 0.25).look
end

Now I’ll try and put together some visuals for this remix, I’ll try and update here once I’m done…

EDIT: And here’s what I came up with… I kind of got lazy and kept it simple.

4 Likes

Nice song!
I wonder if it’s possible to make similar bass/lead synths in sonic pi.

I think the bass sound could mostly be made in Sonic Pi but the issue I was considering is that this type of bass sound uses a short portamento time. So every time a new note is pressed on the keyboard the note glides in pitch from the last note to the new note.

I’m not sure if there’s an easy way to slide the pitch up and down like this to meet the next note but I do recall some people trying to solve this in another thread… maybe search for “portamento” to find that. Or maybe someone else will chime in with a solution. This is why I typically add my synths later in the process.

Another alternative if you happen to own a hardware synth would be to play midi notes in Sonic Pi, then send those notes out via MIDI Cable to the synthesizer (which you could set up to be monophonic and have a short portamento time)… Then record the audio back in to the session with an audio jack.

I think portamento is relatively easy to achive in sonic pi, I can try to make a demo today.

Basically you need to play a synth with a long sustain time, save the note in a variable.
And later you can change played note with control, and glide time is can be controlled with note_slide.

Only problem is that I can see is how you stop the sound, it should either wait some time, if no note is pressed, then kill it, or you can stop sound by pressing a separate key in another live_loop.

Here’s working code for portamento.

The STOP_NOTE is workaround, you can use another event to trigger stopping of the bass (MIDI button, timer or something else). You can change glide time by changing the note_slide parameter

You can use global variable instead of get/set, but I don’t recommend, you will have stuck notes, if you press run twice.

Demo: https://youtu.be/_P8UgGLzTWY

1 Like

Awesome! Thanks for that, I saved that video as a reference to make use of later.