My first "patch" - created Tabla music

Hi all, this is my first postable SP patch. As I’ve seen others do, using the Tabla sample set seems like an obvious target. Firstly… this will not be authentic Tabla music! It’s more an exercise in the high level control.

I wanted to play with the idea of the ebb and flow in music. Something I’ve heard in live Indian music performances… moving from time of calm to periods of frenetic activity.

I hope to use the core building blocks in other creations over time.

Comments on coding, ideas and improvements welcome.

Thanks,

Frank.

# Tabla Improv
#
# Tabla and melodic line, that play from defined patterns and with a changing feel.
#
# Frank Taylor <spi ! lieder.me.uk

# [<pattern>, <freq>] The higher the freq the more likely it is to be chosen.
#
# Order the patterns in increasing spiciness.
pf = [[[1], 2],
      [[2, 2], 3],
      [[2, 4, 4], 4],
      [[4, 4, 2], 4],
      [[4, 2, 4], 4],
      [[4, 4, 4, 4], 4],
      [[8, 8, 8, 8, 4, 4], 3],
      [[16, 16, 8, 8, 16, 16, 8, 8, 4], 3],
      [[16, 16, 16, 16, 16, 16, 16, 16, 4, 16, 16, 16, 16], 3],
      [[3, 3, 3], 1],
      [[3, 3, 6, 6], 1],
      [[6, 6, 3, 6, 6], 1],
      [[5, 5, 5, 5, 5], 0]]

patterns = []
pf.each do |p, n|
  n.times do
    patterns << p
  end
end

# Return a biased rand between 0..1.
# s - start of the focussed section
# e - end of the focussed section
# f - probability to take from the focussed section
#
# E.g. biased_rand(0.5, 0.1, 1.0) -> 0.4...0.6
#      biased_rand(0.5, 0.5, 0.5) -> 0..1, but 50% of the time it will choose a number between 0.4..0.6
#
define :biased_rand do |s, e, f|
  if rand > f
    return rand
  else
    return rand(e - s) + s
  end
end

# Similar to biased_rand, but chooses elements from a list based on focussed section.
# Focus is still specified in 0..1 - fraction of the list.
#
define :biased_choose do |s, e, f, l|
  br = biased_rand(s, e, f)
  s = l.length
  l[s * br]
end

define :choose_pattern do |f, l|
  (s, e, f) = f
  biased_choose(s, e, f, l)
end


feeling_calm = [0.0, 0.25, 1.0]
feeling_mid = [0.0, 0.5, 0.8]
feeling_hot = [0.5, 1.0, 0.5]
feeling_blistering = [0.5, 1.0, 1.0]

# [<feeling>, <freq>]
feeling_prefs = [[feeling_calm, 2],
                 [feeling_mid, 3],
                 [feeling_hot, 2],
                 [feeling_blistering, 1]]

feelings = []
feeling_prefs.each do |p, n|
  n.times do
    feelings << p
  end
end

notes = scale :c2, :indian, num_octaves: 3
note = :c2
feeling = feeling_calm

live_loop :changer do
  sleep 32
  s = [:c2, :f2, :g2].choose
  notes = scale s, [:hindu, :indian, :dorian].choose, num_octaves: 3
  feeling = feelings.choose
  
  puts "Feeling: ", feeling, "New scale: ", s
end

live_loop :tabla do
  p = choose_pattern(feeling, patterns)
  ts = 0.0
  
  p.each do |f|
    puts "Pattern: ", p, feeling
    l = 1.0/f
    s = (sample_names :tabla).choose
    sample s
    ts = ts + l
    sleep l
  end
  
  ds = (1-ts)
  puts "Delay sleep: ", ds
  sleep ds
end

live_loop :melody do
  slow = 2.0
  with_synth :pluck do
    p = choose_pattern(feeling, patterns)
    
    tl = 0.0
    p.each do |f|
      interval = [0, 0, 0, 1, 1, 1, -1, -1, -1, 2, -2, 3, -3, 4, -4].choose
      note = note + interval
      l = slow / f
      tl = tl + l
      puts "Melody: ", p, interval, note, l, notes[note], feeling
      play notes[note], sustain: l, amp: 0.75
      sleep l
    end
    
    ds = (slow - tl)
    sleep ds
  end
end


2 Likes