Weighted randomization

Hie everyone,

First please be indulgent for my bad english.

I am a retired french college teacher in technology. I am interested with computer music, and i play guitar. I use reaper and maschine softwares.

My aim is to introduce weigted probablties to fake a jazz solo. In the fommewing script I use ruby arrays functions. The problems is that my loop stops but not immediately and then suddenly nils arrays problems occure.

ordre_library = [[[0,1,2,1],5],[[0,2,1,0],5],[[2,1,2,0],5],[[1,0,2,1],5]]
times_library = [[[0.25,0.25,0.25,0.25],35],[[0.25,0.25,0.50,0.25],35],[[0.25,0.25,0.50,0.50],30]]




define :lst_prob do |var_prob|
  prob = []
  probcum =[ ]
  probtot = 0
  #var_prob = [[[0.25,0.25,0.25,0.25],10],[[0.25,0.25,0.50,0.25],50],[[0.25,0.25,0.50,0.50],10]]
  l = var_prob.length
  #puts l
  i=0
  l.times do
    prob[i] = var_prob[i][1]
    probcum[i]=probtot+prob[i]
    probtot= probcum[i]
    i=i+1
  end
  #puts probcum
  #puts probtot
  #puts probcum
  probx = rand_i(probtot)+1
  #puts probx
  
  #puts  "cas 1"
  if (probx < probcum[0] )
    #puts "test 1 +"
    var = var_prob[0][0]
    
  end
  
  i = 0
  if (l>2)
    n = l-2
    n.times do
      i= i+ 1
      #puts  "cas 2"
      if (probx >=  probcum[i-1]  &&   probx< probcum[i])
        #puts "test 2 +"
        var = var_prob[i][0]
      end
    end
  end
  #puts  "cas 3"
  if (probx > probcum[l-2] )
    #puts "test 3 +"
    var = var_prob[l-1][0]
  end
  
  return var
end

#creation of scale array from scale ring
define :arrayscale do |x1, x2, x3|
  pattern=[]
  xscale = scale( x1, x2 , x3)
  puts xscale
  l = xscale.length
  i=-1
  l.times do
    i=i+1
    # puts xscale[i]
    pattern[i] = xscale [i]
  end
  # puts pattern
  return pattern
  #creation of scale array from scale ring
end




define :arp1232 do
  ordre = lst_prob ordre_library
  times = lst_prob times_library
  #à chaque itération choix mode
  #m=choose([:aeolian, :ahirbhairav, :augmented, :augmented2, :bartok, :bhairav, :blues_major, :blues_minor, :chinese, :chromatic, :diatonic, :diminished, :diminished2, :dorian, :egyptian, :enigmatic, :gong, :harmonic_major, :harmonic_minor, :hex_aeolian, :hex_dorian, :hex_major6, :hex_major7, :hex_phrygian, :hex_sus, :hindu, :hirajoshi, :hungarian_minor, :indian, :ionian, :iwato, :jiao, :kumoi, :leading_whole, :locrian, :locrian_major, :lydian, :lydian_minor, :major, :major_pentatonic, :marva, :melodic_major, :melodic_minor, :melodic_minor_asc, :melodic_minor_desc, :messiaen1, :messiaen2, :messiaen3, :messiaen4, :messiaen5, :messiaen6, :messiaen7, :minor, :minor_pentatonic, :mixolydian, :neapolitan_major, :neapolitan_minor, :octatonic, :pelog, :phrygian, :prometheus, :purvi, :ritusen, :romanian_minor, :scriabin, :shang, :spanish, :super_locrian, :todi, :whole, :whole_tone, :yu, :zhi])
  # m= [:blues_minor].choose
  #pat = m.combination(4).to_a.choose.sort
  m = arrayscale(:c3, [:blues_minor].choose, num_octaves: 3)
  puts m
  puts m.length
  #extraction of 4 elements array
  notes = m.slice(rand_i(m.length-4),4)
  puts notes
  play notes[ordre[0]]
  sleep times[0]
  play notes[ordre[1]]
  sleep times[1]
  play notes[ordre[2]]
  sleep times[2]
  play notes[ordre[3]]
  sleep times[3]
end



live_loop :loop1 do
  
  
  
  use_bpm 120
  arp1232
  sleep 0.01
  
  
end

Can any one help me

Thanks

Hi @radjoul,

Welcome to the forum! I don’t have an answer right now, but I have a couple of suggestions to make your question easier for others, and hopefully increase the chance of getting the answer you want:

  • If you add three backticks (```) on a line of their own before and after the code, the forum will format it nicely with syntax highlighting, and make it easier to copy into Sonic Pi
  • The code is quite long, so if you can reduce it to a smaller example that still has the problem, that will make it easier for others to follow (and when it’s fixed, feel free to post the complete code again so others can hear your creation!)

Hmm This is quite complex code and not asy to work out all your logic. So far I have just looked at the value of the ordre and times variables created by the arp1232 function. I stripped out all note playing and sleeps due to times values substituting a fixed small sleep 0.1 and then ran the code priting out iterations where either ordre or times were nil. As you can see if you run the code there are many such, but they appear to be fairly randomly distributed. It may be there is a race condition or else a logic fault where you may be trying to access values outside the list length.

ordre_library = [[[0,1,2,1],5],[[0,2,1,0],5],[[2,1,2,0],5],[[1,0,2,1],5]]
times_library = [[[0.25,0.25,0.25,0.25],35],[[0.25,0.25,0.50,0.25],35],[[0.25,0.25,0.50,0.50],30]]
use_debug false



define :lst_prob do |var_prob|
  prob = []
  probcum =[ ]
  probtot = 0
  #var_prob = [[[0.25,0.25,0.25,0.25],10],[[0.25,0.25,0.50,0.25],50],[[0.25,0.25,0.50,0.50],10]]
  l = var_prob.length
  #puts l
  i=0
  l.times do
    prob[i] = var_prob[i][1]
    probcum[i]=probtot+prob[i]
    probtot= probcum[i]
    i=i+1
  end
  #puts probcum
  #puts probtot
  #puts probcum
  probx = rand_i(probtot)+1
  #puts probx
  
  #puts  "cas 1"
  if (probx < probcum[0] )
    #puts "test 1 +"
    var = var_prob[0][0]
    
  end
  
  i = 0
  if (l>2)
    n = l-2
    n.times do
      i= i+ 1
      #puts  "cas 2"
      if (probx >=  probcum[i-1]  &&   probx< probcum[i])
        #puts "test 2 +"
        var = var_prob[i][0]
      end
    end
  end
  #puts  "cas 3"
  if (probx > probcum[l-2] )
    #puts "test 3 +"
    var = var_prob[l-1][0]
  end
  
  return var
end

#creation of scale array from scale ring
define :arrayscale do |x1, x2, x3|
  pattern=[]
  xscale = scale( x1, x2 , x3)
  ##puts xscale
  l = xscale.length
  i=-1
  l.times do
    i=i+1
    # puts xscale[i]
    pattern[i] = xscale [i]
  end
  # puts pattern
  return pattern
  #creation of scale array from scale ring
end




define :arp1232 do
  ordre = lst_prob ordre_library
  times = lst_prob times_library
  #à chaque itération choix mode
  #m=choose([:aeolian, :ahirbhairav, :augmented, :augmented2, :bartok, :bhairav, :blues_major, :blues_minor, :chinese, :chromatic, :diatonic, :diminished, :diminished2, :dorian, :egyptian, :enigmatic, :gong, :harmonic_major, :harmonic_minor, :hex_aeolian, :hex_dorian, :hex_major6, :hex_major7, :hex_phrygian, :hex_sus, :hindu, :hirajoshi, :hungarian_minor, :indian, :ionian, :iwato, :jiao, :kumoi, :leading_whole, :locrian, :locrian_major, :lydian, :lydian_minor, :major, :major_pentatonic, :marva, :melodic_major, :melodic_minor, :melodic_minor_asc, :melodic_minor_desc, :messiaen1, :messiaen2, :messiaen3, :messiaen4, :messiaen5, :messiaen6, :messiaen7, :minor, :minor_pentatonic, :mixolydian, :neapolitan_major, :neapolitan_minor, :octatonic, :pelog, :phrygian, :prometheus, :purvi, :ritusen, :romanian_minor, :scriabin, :shang, :spanish, :super_locrian, :todi, :whole, :whole_tone, :yu, :zhi])
  # m= [:blues_minor].choose
  #pat = m.combination(4).to_a.choose.sort
  m = arrayscale(:c3, [:blues_minor].choose, num_octaves: 3)
  ##puts m
  ##puts m.length
  #extraction of 4 elements array
  notes = m.slice(rand_i(m.length-4),4)
  puts "ordre nil",get(:count)   if ordre ==nil
  puts "times nil",get(:count)   if times ==nil
  ##| play notes[ordre[0]]
  ##| sleep times[0]
  ##| play notes[ordre[1]]
  ##| sleep times[1]
  ##| play notes[ordre[2]]
  ##| sleep times[2]
  ##| play notes[ordre[3]]
  ##sleep times[3]
  sleep 0.1
end



live_loop :loop1 do
  
  #49,61
  
  use_bpm 120
  set :count, tick + 1
  arp1232
  sleep 0.01 
end