Inversion to Develop a Melodic Theme


#1
# Playing a melodic theme using the indices of the notes on a scale
theme1=[0,4,2,0,1,2,3,2,1,5,3,1,0,-1,-2,-1,0]
# use nle array to time the notes
nle=[0.25,0.25,0.25,0.25,0.125,0.125,0.125,0.125] # note length
nle=nle.ring

use_synth :piano
rel= 1.5 # note release
amplitude= 1
# try selecting different key and scale type
key= 'C4'
key1=note(key)
scaletype='major'
kscale=scale(key,scaletype)

# Build array in tune1 of notes using the selected musicalscale
define :buildtune do |invertflg,invertindex,octaveshift|
  tune1=[]
  i=0
  while i<theme1.length
    y=0
    if(invertflg!=0)
      x=invertindex-theme1[i]
    else
      x=theme1[i]
    end
    #  puts i,x
    # need to adjust for several octaves
    if(x<0)
      x+=7
      y=-12
    end
    if(x>7)
      x-=8
      y=8
    end
    if((x-x.floor)>0)
      y+=1
    end
    tune1.push(kscale[x.floor]+y+12*octaveshift)
    i+=1
  end
  return tune1
end
# Build array in tune2 of notes using the selected musicalscale
tune2=buildtune(0,0,0)
puts tune2
# Build inverted array in tune3 of notes using the selected musicalscale
tune3=buildtune(1,2,0)
puts tune3
# zip the arrays together
tune4=tune2.zip(tune3)
puts tune4
# Play the theme in the selected musical scale
with_fx :level, amp: amplitude do
  play_pattern_timed tune2,nle,release: nle[0]*rel
end
# Play the inverted theme in the selected musical scale
with_fx :level, amp: amplitude do
  play_pattern_timed tune3,nle,release: nle[0]*rel
end
# Play the theme and inverted theme in the selected musical scale
with_fx :level, amp: amplitude do
  play_pattern_timed tune4,nle,release: nle[0]*rel
end

## use circle of fifths to modulate the melody thru different keys
cf=0
while cf< 13
  key=kscale[4]
  puts key
  if(key>(key1+12))
    key-=12
  end
  scaletype='major'
  if(cf==5)
    scaletype='romanian_minor'
  end
  kscale=scale(key,scaletype)
  # Build array in tune2 of notes using the selected musicalscale
  xxx=0
  if(cf%3)
    xxx=-1
  end
  tune2=buildtune(0,0,xxx)
  puts tune2
  # Build inverted array in tune3 of notes using the selected musicalscale
  xx=2
  if (cf%2)
    xx=4
  end
  tune3=buildtune(1,xx,0)
  puts tune3
  # zip the arrays together
  tune4=tune2.zip(tune3)
  puts tune4
  # Play the theme in the selected musical scale
  with_fx :level, amp: amplitude do
    play_pattern_timed tune2,nle,release: nle[0]*rel
  end
  # Play the inverted theme in the selected musical scale
  with_fx :level, amp: amplitude do
    play_pattern_timed tune3,nle,release: nle[0]*rel
  end
  # Play the theme and inverted theme in the selected musical scale
  with_fx :level, amp: amplitude do
    play_pattern_timed tune4,nle,release: nle[0]*rel
  end
  
  cf+=1
end