-- Chord Voicing Generator local chord_names = { "maj11","min11", "maj9","min9", "maj7","min7", "maj","min", "dim7", "dim", "aug" } local quantize_steps = {0.0, 0.125, 0.25, 0.5, 0.75, 1.0} return pattern { unit = "1/4", repeats = 0, parameter = { parameter.integer("Random Seed", 0, {0, 99999999}), parameter.enum("Chord", "min9", chord_names), parameter.boolean("3rd +12", true), parameter.boolean("5th +12", false), parameter.boolean("7th add +12", false), parameter.boolean("9th add +12", true), parameter.number("Delay min", 0.001, {0, 1}), parameter.number("Delay max", 0.03, {0, 1}), parameter.boolean("Quantize Delay", false), parameter.boolean("Keep Root on 1", true), parameter.number("Volume min", 0.7, {0.0, 1.0}), }, pulse = {1}, event = function(context) local p = context.parameter -- random seed local rndSeed = p["Random Seed"] if rndSeed > 0 then math.randomseed(rndSeed) end local notes = chord("c4", p.Chord).notes or {} -- transpose 3rd if p["3rd +12"] and notes[2] then notes[2] = note(notes[2]):transpose(12) end -- transpose 5th if p["5th +12"] and notes[3] then notes[3] = note(notes[3]):transpose(12) end -- add upper octave 7th if p["7th add +12"] and notes[4] then local n = note(notes[4]):transpose(12) table.insert(notes, #notes+1, n) end -- add upper octave 9th if p["9th add +12"] and notes[5] then local n = note(notes[5]):transpose(12) table.insert(notes, #notes+1, n) end local delay_min = p["Delay min"] local delay_max = p["Delay max"] local volume_min = p["Volume min"] -- keep root note always on beat 1 local anchor_note = p["Keep Root on 1"] and 1 or nil -- humanize for i = 1, #notes do -- note delay local delay if anchor_note and i == anchor_note then delay = 0 else delay = delay_min + math.random() * (delay_max - delay_min) if p["Quantize Delay"] then local nearest = quantize_steps[1] local nearest_dist = math.abs(delay - nearest) for j = 2, #quantize_steps do local step = quantize_steps[j] local dist = math.abs(delay - step) if dist < nearest_dist then nearest = step nearest_dist = dist end end delay = nearest end end -- note volume local volume = volume_min + math.random() * (1.0 - volume_min) -- note result notes[i] = note(notes[i]):delay(delay):volume(volume) end return notes end }