Markov melody generator (first-order but i’m ultimately heading for a second-order one). Interaction is a bit limited for now but it is just a foundation.
-- Markov melody generator
-- Key 2 randomize Scale
-- Key 3 randomize Probabilities
engine.name = "PolyPerc"
Scale = {0,0,0,0,0,0,0}
Prob = {{},{},{},{},{},{},{}}
function init()
rndScale()
rndProb()
engine.amp(1.5)
w = 1
noteSel = 1 -- note selector
counter = metro.alloc(count, 0.15, -1)
counter:start()
end
function redraw()
screen.clear()
screen.aa(0)
screen.font_face(1)
screen.font_size(8)
for i=1, 7 do -- Draws Notes
screen.move(15*i, 6)
screen.level(15)
screen.font_face(1)
screen.text_center(Scale[i])
for j=1, 7 do -- Draws probability for each note
screen.move(15*i, 10 + (j*7))
screen.level(2)
screen.text_center(Prob[i][j])
end
end
screen.move(11, 9)
screen.line(110, 9) -- Line
screen.stroke()
screen.rect((w*15-1),8,4,1) -- Feedback
screen.level(5)
screen.stroke()
screen.update()
end
-- Counter
function count()
probRoll()
engine.hz(midi_to_hz(60 + noteSel))
redraw()
end
-- Random Scale Generator
function rndScale()
for i=1, 7 do
if i ~= 1 then
Scale[i] = Scale[i-1] + math.random(1,3) -- Creates Scale{}
end
end
end
-- Random Prob Gen per note
function rndProb()
for i=1, 7 do
remain = 100
deck = {1,2,3,4,5,6,7}
shuffleTable(deck) -- random distribution order
for j=1, 7 do
Prob[i][deck[j]] = (math.random(0, remain)) -- Mixup tables or last probs 0
if Prob[i][deck[j]] == 100 then -- Prevent 100%
Prob[i][deck[j]] = 99
end
remain = (remain - Prob[i][deck[j]])
end
end
end
-- Midi to Hz
function midi_to_hz(note)
local hz = (440 / 32) * (2 ^ ((note - 9) / 12))
return hz
end
-- Prob roll
function probRoll()
local v = 1
repeat
Test = math.random(100)
if Test > Prob[w][v] then
v = v+1
if v > 7 then v = 1 end
x = false
else x = true
end
until x == true
w = v
noteSel = Scale[w]
end
function shuffleTable(t) -- shuffle table content
for ite = #t, 2, -1 do
local shf = math.random(1, ite)
t[ite], t[shf] = t[shf], t[ite]
end
end
function key(n, z) -- Key2 change Scale, Key 3 chang Probs
if n == 2 then
if z == 1 then
rndScale()
end
end
if n == 3 then
if z == 1 then
rndProb()
end
end
redraw()
end