Improvisations over chord progressions

Following up the thread on chord progressions here I have explored the field a bit further.

The piece shows some chord patterns as used in Jazz and also a modulation from key F to C and back. The improvisation loop uses the notes from the scales associated with the chords and keys, plus some random modifications.

### Jazz Improvisations
use_debug false
use_random_seed 30
use_bpm 120

# progressions = list of degrees (or steps)
p1 = [:i, :ii, :v, :i]
p2 = [:ii, :i, :v, :i]
p3 = [:iii, :vii, :vi, :ii]
p4 = [:vii, :ii, :v, :i]

my_piece = (ring
            {:prog => p1, :key => :F2, :mode => :major},
            {:prog => p2, :key => :C3, :mode => :major},
            {:prog => p3, :key => :C3, :mode => :major},
            {:prog => p4, :key => :A2, :mode => :harmonic_minor},
            )

# degree - mode associations
# see https://en.wikipedia.org/wiki/Mode_(music)#Modern_modes
scales = {
  :i => :ionian,
  :ii => :dorian,
  :iii => :phrygian,
  :iv => :lydian,
  :v => :mixolydian,
  :vi => :aeolian,
  :vii => :locrian
}

scales_m = {
  :i => :melodic_minor_asc,
  :ii => :hex_phrygian,
  :iii => :lydian_minor,
  :iv => :minor_pentatonic,
  :v => :augmented,
  :vi => :minor_pentatonic,
  :vii => :super_locrian
}

live_loop :parse_progressions, auto_cue: false, delay: 0.2 do
  pr = my_piece.tick
  pr[:prog].each do |deg|
    if pr[:mode] == :major
      mode = scales[deg]
    else
      mode = scales_m[deg]
    end
    c_chord = (chord_degree deg, pr[:key], pr[:mode], 4)
    puts pr[:key], note_info(c_chord[0]), mode
    set :chord, c_chord
    set :mode, mode
    sleep 4
  end
end

with_fx :reverb, mix: 0.4, room: 0.7 do
  live_loop :my_drums, auto_cue: false do
    sync :chord
    
    define :p do |i|
      a = 1.0
      case i
      when 0
        sample :drum_heavy_kick, amp: a*1.5
      when 1
        sample :drum_snare_soft, amp: a*1.5
      when 2
        sample :drum_cymbal_closed, amp: a*0.7
      end
    end
    
    tick_reset
    24.times do |n|
      tick
      p(0) if ("x-----------------------"[look]=="x")
      p(1) if ("--------------------x---"[look]=="x")
      p(2) if ("x--x-xx--x-xx--x-xx--x-x"[look]=="x")
      sleep 1.0/6 if n < 23
    end
  end
end

with_synth :fm do
  use_synth_defaults amp: 0.6, attack: 0.01, sustain: 0.9, release: 0.1, divisor: 2
  live_loop :bass, auto_cue: false do
    sync :chord
    sca = scale get(:chord)[0], get(:mode)
    notes = (knit sca[0], 3, sca[1], 1, sca[2], 2, sca[4], 2).pick(4)
    notes.each_with_index do |n, i|
      play n
      sleep 1 if i < 3
    end
  end
end

with_fx :reverb, mix: 0.4, room: 0.7 do
  with_synth :piano do
    use_synth_defaults amp: 1.8, hard: 0.65, sustain: 0.2, release: 1.3
    live_loop :piano, auto_cue: false do
      sync :chord
      cho = get(:chord)
      tick_reset
      12.times do |n|
        play cho if ("x---x--x--x-"[tick]=="x")
        sleep 1.0/3 if n < 11
      end
    end
  end
end


with_fx :echo, mix: 0.3, decay: 0.5, phase: 1.0/6 do
  with_synth :pulse do
    use_synth_defaults amp: 0.5, sustain: 0.1
    live_loop :melody, auto_cue: false do
      sync :chord
      sca = scale get(:chord)[0], get(:mode), num_octaves: 3
      num_notes = (knit 12, 4, 9, 1).choose
      start = rrand_i(0, sca.length - num_notes)
      notes = sca[start, num_notes]
      notes = notes.reverse if one_in(3)
      notes.each_with_index do |n, i|
        n = notes[i - 1] if one_in(6) and i > 0
        play n, release: 6.0/num_notes unless one_in(15)
        sleep 4.0/num_notes if i < num_notes - 1
      end
    end
  end
end
3 Likes