Hello Sonic Pi community,
Here’s a little experiment with generative music. It’s rather monotonus, but I couldn’t figure out a way off reusing generated sections. It is also very resource intensive.
Greetings
Loop
# Melody Maker
# Coded by Loopiloop
#---options---
#set random seed. play around with this value
use_random_seed 93847
#root of the key
key_root = rrand_i(48, 60)
#quality of the key
key_qual = :major
#chord progression
chordprog = (ring :i, :v, :vi, :iv)
#---setup---
#pattern of accents for every beat
accent = (ring 1, 0, 0, 0)
#the melody is created randomly out of the first four notes of each chord
c = (ring 0, 1, 2, 3)
#generating melodies
melody_1 = c.pick(16) #square lead
melody_2 = c.pick(16) #square base
melody_3 = c.pick(16) #wave lead
#this variable is used to create random lists of boleans and for on-off patterns
ft = (ring 0, 1)
#generating rythms
onoff_1 = ft.pick(16) #square lead
onoff_2 = ft.pick(16) #square base
onoff_3 = ft.pick(16) #wave lead
onoff_4 = ft.pick(16) #drums
#define how much score a pattern gets for a note in each position
importance = (ring 4, 0, 1 ,0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0)
#add samples to list for automated sample choice and load them
drum = [:drum_bass_soft, :drum_bass_hard]
load_samples drum
#current position within the song in bars
cprogpos = 0
#current position within the song in sixteenth notes
sixteenth = 0
#offset of currently evaluated variation in relation to original pattern
evaluate_n = 0
#position in evaluated variation
evaluate_i = 0
#square lead evaluation variables
evaluate_s_1 = 0 #score of current variation
evaluate_t_1 = 0 #score of best variation
evaluate_r_1= 0 #offset of best variation
#square base evaluation variables
evaluate_s_2 = 0 #score of current variation
evaluate_t_2 = 0 #score of best variation
evaluate_r_2 = 0 #offset of best variation
#wave lead evaluation variables
evaluate_s_3 = 0 #score of current variation
evaluate_t_3 = 0 #score of best variation
evaluate_r_3 = 0 #offset of best variation
#drums evaluation variables
evaluate_s_4 = 0 #score of current variation
evaluate_t_4 = 0 #score of best variation
evaluate_r_4 = 0 #offset of best variation
#---pattern optimization---
#iterate through pattern variations
16.times do
  
  #return to first position
  evaluate_i = 0
  
  #reset scores
  evaluate_s_1 = 0 #square lead
  evaluate_s_2 = 0 #square base
  evaluate_s_3 = 0 #wave lead
  evaluate_s_4 = 0 #drums
  
  #iterate through positions
  16.times do
    
    #square lead
    #if theres a note at the current position
    if 1 == onoff_1[evaluate_n + evaluate_i]
      #add importance of the current position to the score
      evaluate_s_1 = evaluate_s_1 + importance[evaluate_i]
    end
    
    #square base
    #if theres a note at the current position
    if 1 == onoff_2[evaluate_n + evaluate_i]
      #add importance of the current position to the score
      evaluate_s_2 = evaluate_s_2 + importance[evaluate_i]
    end
    
    #wave lead
    #if theres a note at the current position
    if 1 == onoff_3[evaluate_n + evaluate_i]
      #add importance of the current position to the score
      evaluate_s_3 = evaluate_s_3 + importance[evaluate_i]
    end
    
    #drums
    #if theres a note at the current position
    if 1 == onoff_4[evaluate_n + evaluate_i]
      #add importance of the current position to the score
      evaluate_s_4 = evaluate_s_4 + importance[evaluate_i]
    end
    
    #move to next position
    evaluate_i = evaluate_i +1
  end
  
  #square lead
  #if current variant was better then the so far best variant
  if  evaluate_s_1 > evaluate_t_1
    #set variant high score to score of current one
    evaluate_t_1 = evaluate_s_1
    #set offset of best variant to offset of current one
    evaluate_r_1 = evaluate_n
  end
  
  #square base
  #if current variant was better then the so far best variant
  if  evaluate_s_2 > evaluate_t_2
    #set variant high score to score of current one
    evaluate_t_2 = evaluate_s_2
    #set offset of best variant to offset of current one
    evaluate_r_2 = evaluate_n
  end
  
  #wave lead
  #if current variant was better then the so far best variant
  if  evaluate_s_3 > evaluate_t_3
    #set variant high score to score of current one
    evaluate_t_3 = evaluate_s_3
    #set offset of best variant to offset of current one
    evaluate_r_3 = evaluate_n
  end
  
  #drums
  #if current variant was better then the so far best variant
  if  evaluate_s_4 > evaluate_t_4
    #set variant high score to score of current one
    evaluate_t_4 = evaluate_s_4
    #set offset of best variant to offset of current one
    evaluate_r_4 = evaluate_n
  end
  
  #move to next variant
  evaluate_n = evaluate_n + 1
end
#---playing the music---
#do forever
  live_loop :main do
    
    #iterate through four bars
    4.times do
      
      #iterate through sixteen sixteenth notes
      16.times do
        
        #synth for the square instuments
        use_synth :chiplead
        
        #square lead
        play (chord_degree chordprog[cprogpos], key_root, key_qual)[melody_1[sixteenth]],on: onoff_1[sixteenth+evaluate_r_1], release: 0.25, amp: 0.25
        
        #square lead base an octave lower
        play (chord_degree chordprog[cprogpos], key_root, key_qual)[melody_2[sixteenth]]-12,on: onoff_2[sixteenth+evaluate_r_2], release: 0.25, amp: 0.25
        
        #only on eighth notes
        if ft[sixteenth+1]
          
          #synth for wave lead
          use_synth :chipbass
          
          #wave lead
          play (chord_degree chordprog[cprogpos], key_root, key_qual)[melody_3[sixteenth]],on: onoff_3[sixteenth+evaluate_r_3], release: 0.25, amp: 0.5
        end
        
        #drums according to accent pattern
        sample drum[accent[sixteenth]],amp: 1
        
        #move to next sixteenth
        sixteenth = sixteenth + 1
        
        #wait for current sixteenth to end
        sleep 0.125
      end
      
      #move to next chord
      cprogpos = cprogpos + 1
    end
  end
 
