Programmatically Creating Live Loops On The Fly


#1

Is there a way to create a live_loop on the fly, programmatically?

The way I know how to make live_loops is like this:

live_loop :fixedname do
     # Do Something
     Sleep 1     
end

Is it possible to have “:fixedname” be something dynamic, that can be created during runtime? In other words, would it be possible to create a series of live_loops where the name is created on the fly, based on strings from an array? Ultimately, I’m hoping to create a bunch of loops that have unique names so that each can have their own timing.

Thanks for taking a look, community!! :slight_smile:


#2

I figured it out! Thought I’d share for anybody else who might be trying to solve the same problem:

define :createloop do |loopname, looptiming|
	live_loop loopname.to_sym do
		sleep looptiming
		print loopname.upcase + ": " + looptiming.to_s
	end
end

looparray = ["loop1", "loop2", "loop3", "loop4"]
looptimes = [1, 3, 8, 2]

looparray.each do
	createloop looparray[tick], looptimes[look]
	print "BOOM!"
	sleep 1
end

Happy coding, friends! :slight_smile:


#3

Thank you. I was thinking about doing that the other day and now I have a solution. Great work.


#4

Sweet! Glad I could help @Bubo :slight_smile:


#5

I did something like this some time ago in a project

Here is a progam which creates 7 different live loops based on different loop samples. These can be chosem whenver you like and can be stopped again whebver you like.
In this demo each loop is played in sequence for 8 beats and then the next one starts,

live_loop :metro do #metronome to sync stuff together
  sleep 1
end


define :doLoop do |n,vol,sampleName,bs|
  set ("c"+n.to_s).to_sym,1
  set ("kill"+n.to_s).to_sym,false
  ln=("name"+n.to_s).to_sym
  in_thread do
    loop do
      if get( ("c"+n.to_s).to_sym)==0
        s= get( ("s"+n.to_s).to_sym)
        kill s
        set ("kill"+n.to_s).to_sym, true
        stop
      end
      sleep 0.1
    end
  end
  live_loop  ln, sync: :metro do
    s=sample sampleName,beat_stretch: bs,amp: vol
    set ("s"+n.to_s).to_sym,s
    k=(bs/0.1).to_i
    k.times do
      sleep bs.to_f/k
      stop if get( ("kill"+n.to_s).to_sym)
    end
  end
end

define :doCommandSelect do |n|
  puts n
  case n
  when 0
    doLoop 0,0.5,:loop_amen,4 #parameters: channel,vol,samplename,beatstrech value
  when 1
    doLoop 1,0.5,:loop_garzul,16
  when 2
    doLoop 2,0.8,:loop_compus,16
  when 3
    doLoop 3,0.9,:loop_mehackit1,4
  when 4
    doLoop 4,0.7,:loop_mika, 16
  when 5
    doLoop 5,0.7, :loop_weirdo, 4
  when 6
    doLoop 6,0.7, :loop_mehackit2,4
  else
    puts "Do Nothing"
  end
end



7.times do |n|
  doCommandSelect n
  sleep 16
  set ("c"+n.to_s).to_sym,0
end

You can see the original project in operation in this video.


#6

Nice work, @robin.newman! Your youtube videos have already inspired me to experiment with touchOSC, and now I can appreciate your solution to this as well! Thanks for sharing your hard work with me and the rest of the coding community! :slight_smile:


#7

Just to add another solution: I also had to generate live_loops on the fly. In my case the number of loops depends on the user configuration so I had to access the live_loops name and several other variables (e. g. knobs of the Midi controller) by index. Thats why I created a config array which contains sub entries with variable names. This array I can access with Ruby’s size expression and an index. After the config array follows the actual binding of the values to the variables. If you are interested: