Help with CHOOSE

n=[]
define :bass do; synth :fm, note: n, release: 1.0, amp: 1; end
define :mari do; synth :pretty_bell, note: n, release: 0.2, amp: 1; end
define :guit do; synth :pluck, note: n, release: 2, amp: 1; end
#  Want to play single instrument for each note ........
# As is all 3 playing each note in unison .....
loop do
  n=choose([40,50,60])
  choose([bass,mari,guit])
sleep 0.5; end

The problem here is that writing the name of the function is enough to call it, so every time around the loop you are creating an array with the results of calling all 3 functions.
You can get around this by choosing symbols instead:
choose([:bass, :mari, :guit]), but then you need a way to actually call the function named by the resulting symbol. You can do it using Ruby’s to_proc and call like this:

n=[]
define :bass do; synth :fm, note: n, release: 1.0, amp: 1; end
define :mari do; synth :pretty_bell, note: n, release: 0.2, amp: 1; end
define :guit do; synth :pluck, note: n, release: 2, amp: 1; end
loop do
  n=choose([40,50,60])
  choose([:bass, :mari, :guit]).to_proc.call(self)
  sleep 0.5;
end

I found that you need to pass self into the function to make it work - I’m not completely sure why. Also, uses Ruby internals that are not really supported on Sonic Pi so it might not work in all versions of Sonic Pi.
A better, but more verbose way might be something like this:

n=[]
define :bass do; synth :fm, note: n, release: 1.0, amp: 1; end
define :mari do; synth :pretty_bell, note: n, release: 0.2, amp: 1; end
define :guit do; synth :pluck, note: n, release: 2, amp: 1; end

define :call_proc do |p|
  if p == :bass then
    bass
  elsif p == :mari then
    mari
  elsif p == :guit then
    guit
  end
end

loop do
  n=choose([40,50,60])
  call_proc choose([:bass, :mari, :guit])
  sleep 0.5;
end
b=[:fm,0.5,1.0]; g=[:pluck,2.0,1.0]; m=[:pretty_bell,0.2,1.0]
# simpler way
loop  do
  s=choose([g,b,m])
  n=choose([45,50,55])
  synth s[0], note: n, release: s[1], amp: s[2]
sleep 0.35; end
1 Like