Carrying on from a convo a month ago (solved by d0lfyn)

related to this topic

So I have this melody:

live_loop :Melody do
  sample :habanera
  use_synth :fm
  use_transpose -12
  play (ring :d, :r, :r, :a, :f5, :r, :a, :r).tick
  sleep 0.25
end

but when I use this code:

  if tick == 3
    set :run, 0
    stop
  end

to automatically stop it, it breaks the melody.

live_loop :Melody do
  sample :habanera
  use_synth :fm
  use_transpose -12
  play (ring :d, :r, :r, :a, :f5, :r, :a, :r).tick
  sleep 0.25
  if tick == 3
    set :run, 0
    stop
  end
end

can anyone help make it so that the melody doesn’t break?

thanks.

Hi again :slight_smile:

You should use look == 3 if you only intend to check the tick value. tick advances the tick value whenever it’s invoked.

It would look like this:

  if look == 3
    set :run, 0
    stop
  end
2 Likes

this worked. now I need to figure out how many individual habanera sounds I need so I know when to stop the melody :joy::joy:
thanks heaps

1 Like

@Future - just a suggestion - IMO it’s very useful if you give the link some descriptive text, (for example, many folks recommend writing links like β€˜see [how to xyz]’ instead of using something like β€˜for how to xyz, [click here]’). This gives much more immediate context about what the link points to :slight_smile: Even better in this case though, you can allow discourse to show a preview of the page that you are linking to, if you place the link on its own line :grinning_face_with_smiling_eyes:

1 Like

carrying on again: how do I do this with my own samples? I’ve been trying for ages with no success.

in_thread do
  live_loop :clap do
    sample clap, :d.tick, amp: 2
    sleep 2
  end
  if look == 2
    set :run, 0
    stop
  end
end

This doesn’t work, along with a bunch of other ways I tried. fyi - clap is the name of a sample.

Long time no see!

Hmm, here’s a template solution, which I’ll try to explain:

use_bpm 120

##| initialise time state variable :run
set :run, true

live_loop :kick do
  ##| alternate between loud and soft
  sample :drum_bass_soft, amp: [0.8, 0.4].ring.tick
  sleep 1
  
  stop unless get :run
end

in_thread do
  ##| offset by 1 beat
  sleep 1
  live_loop :snare do
    sample :drum_snare_soft, amp: 0.8
    sleep 2
    
    stop unless get :run
  end
end

with_synth :tri do
  live_loop :arp do
    ##| cycle through arpeggio ring
    play [:a3, :c4, :e4].ring.tick, amp: 0.6, sustain: 0, release: 1/8.to_f
    sleep 1/4.to_f
    
    stop unless get :run
  end
end

live_loop :clock do
  ##| advance tick up to limit
  if tick == 6
    set :run, false
    stop
  end
  sleep 1
end

Basically, you want to keep a separate clock loop the moment you have more than one loop you want to synchronise to stop.

Notice how each live_loop keeps its own tick, whereas the time state variable :run is shared everywhere.

In this template, you can also see how a snare (or clap) can be offset by a beat using an in_thread on its inception.

I hope this helps! :slight_smile:

1 Like

I’ve set the clap to tick twice for experimenting sake, but it is not turning itself off after 2, it was doing it after 11.

Also, my drums all come in different times, but I want them all to cut out at the same time. will this clock thing allow that?

code:

# Written by Sam Humphreys

#––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

# Setting BPM to 70
use_bpm 70

#––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

# Making variables:

# The clap is a single one-shot hit, that I repeat every two seconds on line 67
clap = "/Users/samhumphreys/Library/Mobile Documents/com~apple~CloudDocs/Logic Pro X/Music Plug-Ins/Cymatics/Cymatics - Drill Essential Drum Kit/Drum One Shots/Claps/Cymatics - Wake Clap.wav"

# The hi hats is a loop that I created on Logic Pro, and then bounced out as a .aif file.
# I made the loop on Logic because I thought it would be too hard to make a good
# sounding hi hat loop on Sonic Pi because of my experience with it (absolutely zero).
hi_hats = "/Users/samhumphreys/Library/Mobile Documents/com~apple~CloudDocs/2020/2021/TeKura/Music/SonicPi/bouncedLoops/Hi-hat-loop-for-Sonic-Pi.wav"

# The 808 is another loop I made on Logic, for the same reason as the hi hat loop. The 808s are
# way to complicated to make in Sonic Pi for someone with my knowledge of Ruby and Sonic Pi.
bass = "/Users/samhumphreys/Library/Mobile Documents/com~apple~CloudDocs/2020/2021/TeKura/Music/SonicPi/bouncedLoops/SonicPiBass.wav"

# This is the kick. I was going to make this loop in Logic again but I thought that if I did too much in Logic, my grade would be lowered.
kick = "/Users/samhumphreys/Library/Mobile Documents/com~apple~CloudDocs/Logic Pro X/Music Plug-Ins/Cymatics/Cymatics - Drill Essential Drum Kit/Drum One Shots/Kicks/Cymatics - Ultimate Kick - G.wav"

# This is the perc loop. Made on Logic again.
perc = "/Users/samhumphreys/Library/Mobile Documents/com~apple~CloudDocs/2020/2021/TeKura/Music/SonicPi/bouncedLoops/Percloop.aif"

# This is a white noise up effect.
wn_u_fx = "/Users/samhumphreys/Library/Mobile Documents/com~apple~CloudDocs/Logic Pro X/Music Plug-Ins/Cymatics/Cymatics - FX Essentials/White Noise/Up/Cymatics - FX Essentials White Noise Riser 18 - 140 BPM.wav"

# This is an impact effect.
impact = "/Users/samhumphreys/Library/Mobile Documents/com~apple~CloudDocs/Logic Pro X/Music Plug-Ins/Cymatics/Cymatics - FX Essentials/Impacts/Cymatics - FX Essentials Impact 2.wav"

# This is a white noise down effect.
wn_d_fx = "/Users/samhumphreys/Library/Mobile Documents/com~apple~CloudDocs/Logic Pro X/Music Plug-Ins/Cymatics/Cymatics - FX Essentials/White Noise/Down/Cymatics - FX Essentials White Noise Downlifter 6.wav"

#––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

# Melody
live_loop :melody do
  sample :habanera
  use_synth :fm
  use_transpose -12
  play (ring :d, :r, :r, :a, :f5, :r, :a, :r).tick
  sleep 0.25
  if look == 257
    set :run, 0
    stop
  end
end

with_fx :reverb do
  live_loop :dNote do
    with_fx :slicer, phase: 0.25 do
      use_synth :blade
      play :d.tick, release: 8, cutoff: 100, amp: 2
    end
    sleep 8
    if look == 7
      set :run, 0
      stop
    end
  end
end


#––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

set :run, true


sleep 16

in_thread do
  live_loop :clap do
    sleep 1
    sample clap, amp: [2].ring.tick
    sleep 1
    
    stop unless get :run
  end
end


in_thread do
  loop do
    with_fx :distortion do
      sample bass, amp: [1].ring.tick
      sleep 16
      
      stop unless get :run
    end
  end
end


sleep 8

in_thread do
  loop do
    sample wn_u_fx .ring.tick
    sleep 32
    
    stop unless get :run
  end
end


sleep 8

in_thread do
  loop do
    sample hi_hats .ring.tick
    sleep 16
    
    stop unless get :run
  end
end

in_thread do
  loop do
    sample kick, amp: [2].ring.tick
    sleep 0.25
    sample kick
    sleep 1.25
    sample kick
    sleep 1
    sample kick
    sleep 0.75
    sample kick
    sleep 0.75
    sample kick
    sleep 0.75
    sample kick
    sleep 0.75
    sample kick
    sleep 1
    sample kick
    sleep 1.5
    
    stop unless get :run
  end
end


in_thread do
  loop do
    sample perc .ring.tick
    sleep 16
    
    stop unless get :run
  end
end


in_thread do
  loop do
    sample impact .ring.tick
    sleep 32
    
    stop unless get :run
  end
end

in_thread do
  loop do
    sample wn_d_fx .ring.tick
    sleep 32
    
    stop unless get :run
  end
end

live_loop :clock do
  if tick == 2
    set :run, false
    stop
  end
  sleep 1
end
  1. The 2 intermediate calls to sleep 8 that you’ve placed in the main thread block the onset of the clock loop for a total of 16 beats. That’s why it claps 11 times: the countdown hasn’t begun. To fix this, I would put the calls to sleep inside each thread individually. That way, they don’t block the clock.
    E.g.
in_thread do
  sleep 8
  loop do
    sample wn_u_fx .ring.tick
    sleep 32
    
    stop unless get :run
  end
end
  1. While it may not affect what you hear, the irregular sleep times in your loops (e.g. sleep 16 and sleep 32) mean that the loops detect the change of :run at different times. To fix this, I would sleep at the same interval of 1 beat in every loop. I would use the modulus operator to determine when to play.
    E.g.
in_thread do
  sleep 8
  loop do
    sample wn_u_fx if (tick % 32).zero?
    sleep 1
    
    stop unless get :run
  end
end

Because the onset of your latest loop is delayed by up to 16 beats, your clock should run for at least 16 beats. Any shorter, and you’ll have stuff playing when it shouldn’t.

If you follow 1 and 2, then the drums should cut out at the same time.

1 Like

I got your first point done, but I don’t understand your second point about the modulus operator. can you pls try to explain a bit more simpler? thanks for your patience

Certainly! I’ll illustrate what I mean with my DAW.

Currently, you have code for several β€œtracks” that end at different times:

image

The reason these tracks end at different times is that their sleep times are different. As a result, the tracks don’t check for the end of the piece until their sleep is over.

What we want is for all our tracks to end at the same time:

image

In order to do this, every track needs to check for the end of the piece at the same time. That’s why I replaced your different sleep times (e.g. 8, 16, 32) with the same sleep time: 1. But because each loop is only sleeping for 1 beat now, everything is playing on every beat! So to get the instruments to play once every 8, 16, or 32 beats, I add a condition to their play statements depending on how frequently they’re supposed to play. E.g. if (tick % 32).zero? plays every 32 beats, meanwhile if (tick % 16).zero? plays every 16 beats.

I hope this clears things up a bit? Please feel free to ask for more clarification. I don’t know if I’ve done a good job simplifying.

2 Likes

awesome. I understand now. Ill probably get back to you tomorrow about how this is going. thanks so much!

1 Like