415 lines
8.7 KiB
Lua
415 lines
8.7 KiB
Lua
-- teach the musicator
|
|
-- uses samples from: https://magenta.tensorflow.org/datasets/maestro#v300
|
|
|
|
--require("luarocks.loader")
|
|
--require("luamidi")
|
|
|
|
require("./musicator")
|
|
local inspect = require("inspect")
|
|
|
|
math.randomseed(os.time())
|
|
|
|
function flatten(v)
|
|
local res = {}
|
|
local function flatten(v)
|
|
if type(v) ~= "table" then
|
|
table.insert(res, v)
|
|
return
|
|
end
|
|
for _, v in ipairs(v) do
|
|
flatten(v)
|
|
end
|
|
end
|
|
flatten(v)
|
|
return res
|
|
end
|
|
|
|
|
|
local training_data = {
|
|
|
|
-- simple ascending phrase
|
|
{
|
|
"C-4","...","D-4","...","E-4","...","G-4","...",
|
|
"E-4","...","D-4","...","C-4","...","...","..."
|
|
},
|
|
|
|
-- descending answer
|
|
{
|
|
"G-4","...","F-4","...","E-4","...","D-4","...",
|
|
"C-4","...","D-4","...","E-4","...","...","..."
|
|
},
|
|
|
|
-- arpeggio major
|
|
{
|
|
"C-4","...","E-4","...","G-4","...","C-5","...",
|
|
"G-4","...","E-4","...","C-4","...","...","..."
|
|
},
|
|
|
|
-- arpeggio minor
|
|
{
|
|
"A-4","...","C-5","...","E-5","...","A-5","...",
|
|
"E-5","...","C-5","...","A-4","...","...","..."
|
|
},
|
|
|
|
-- stepwise melody (folk-like)
|
|
{
|
|
"D-4","...","E-4","...","F-4","...","G-4","...",
|
|
"F-4","...","E-4","...","D-4","...","...","..."
|
|
},
|
|
|
|
-- repeated note rhythm
|
|
{
|
|
"C-5","C-5","...","C-5","...","C-5","C-5","...",
|
|
"D-5","...","E-5","...","...","...","...","..."
|
|
},
|
|
|
|
-- bounce pattern
|
|
{
|
|
"C-5","...","G-4","...","C-5","...","G-4","...",
|
|
"D-5","...","A-4","...","D-5","...","...","..."
|
|
},
|
|
|
|
-- scale run up
|
|
{
|
|
"C-4","D-4","E-4","F-4","G-4","A-4","B-4","C-5",
|
|
"...","...","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- scale run down
|
|
{
|
|
"C-5","B-4","A-4","G-4","F-4","E-4","D-4","C-4",
|
|
"...","...","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- syncopated feel
|
|
{
|
|
"C-5","...","...","D-5","...","...","E-5","...",
|
|
"C-5","...","...","G-4","...","...","...","..."
|
|
},
|
|
|
|
-- triplet-ish feel (simulated)
|
|
{
|
|
"E-5","D-5","C-5","...","E-5","D-5","C-5","...",
|
|
"G-4","...","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- small jumps
|
|
{
|
|
"C-5","...","E-5","...","D-5","...","F-5","...",
|
|
"E-5","...","C-5","...","...","...","...","..."
|
|
},
|
|
|
|
-- call
|
|
{
|
|
"G-4","...","A-4","...","C-5","...","A-4","...",
|
|
"...","...","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- response
|
|
{
|
|
"E-4","...","F-4","...","G-4","...","F-4","...",
|
|
"D-4","...","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- denser pattern (DDR-like)
|
|
{
|
|
"C-5","D-5","E-5","...","D-5","E-5","F-5","...",
|
|
"E-5","D-5","C-5","...","...","...","...","..."
|
|
},
|
|
|
|
-- alternating pattern (good for gameplay)
|
|
{
|
|
"C-5","...","E-5","...","C-5","...","E-5","...",
|
|
"D-5","...","F-5","...","D-5","...","...","..."
|
|
},
|
|
|
|
-- higher register variant
|
|
{
|
|
"G-5","...","A-5","...","B-5","...","D-6","...",
|
|
"B-5","...","A-5","...","G-5","...","...","..."
|
|
},
|
|
|
|
-- low register grounding
|
|
{
|
|
"C-4","...","G-3","...","C-4","...","G-3","...",
|
|
"F-3","...","C-4","...","...","...","...","..."
|
|
},
|
|
|
|
-- variant of ascending with offset
|
|
{
|
|
"...","C-4","...","D-4","...","E-4","...","G-4",
|
|
"...","E-4","...","D-4","...","C-4","...","..."
|
|
},
|
|
|
|
-- staggered rhythm
|
|
{
|
|
"C-4","...","...","D-4","...","E-4","...","...",
|
|
"G-4","...","E-4","...","D-4","...","...","..."
|
|
},
|
|
|
|
-- broken arpeggio (different spacing)
|
|
{
|
|
"C-4","E-4","...","G-4","...","C-5","...",
|
|
"G-4","E-4","...","C-4","...","...","...","..."
|
|
},
|
|
|
|
-- minor variation (shifted)
|
|
{
|
|
"...","A-4","C-5","...","E-5","...","A-5","...",
|
|
"E-5","...","C-5","...","A-4","...","...","..."
|
|
},
|
|
|
|
-- repeated + variation
|
|
{
|
|
"D-4","D-4","...","E-4","...","F-4","F-4","...",
|
|
"G-4","...","F-4","...","E-4","...","...","..."
|
|
},
|
|
|
|
-- zig-zag motion
|
|
{
|
|
"C-5","...","E-5","...","D-5","...","F-5","...",
|
|
"E-5","...","G-5","...","F-5","...","...","..."
|
|
},
|
|
|
|
-- alternating step/jump
|
|
{
|
|
"C-5","...","D-5","...","G-5","...","F-5","...",
|
|
"E-5","...","C-5","...","D-5","...","...","..."
|
|
},
|
|
|
|
-- denser burst pattern
|
|
{
|
|
"C-5","D-5","E-5","F-5","...","E-5","D-5","C-5",
|
|
"...","...","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- rolling pattern
|
|
{
|
|
"E-5","...","D-5","...","C-5","...","D-5","...",
|
|
"E-5","...","G-5","...","E-5","...","...","..."
|
|
},
|
|
|
|
-- syncopation variant
|
|
{
|
|
"...","C-5","...","...","E-5","...","...","G-5",
|
|
"...","E-5","...","C-5","...","...","...","..."
|
|
},
|
|
|
|
-- low-high interplay
|
|
{
|
|
"C-4","...","G-4","...","C-5","...","G-4","...",
|
|
"E-4","...","C-4","...","...","...","...","..."
|
|
},
|
|
|
|
-- descending but staggered
|
|
{
|
|
"C-5","...","...","B-4","...","A-4","...","...",
|
|
"G-4","...","F-4","...","E-4","...","...","..."
|
|
},
|
|
|
|
-- small trill-like feel
|
|
{
|
|
"E-5","F-5","E-5","...","E-5","F-5","E-5","...",
|
|
"D-5","...","C-5","...","...","...","...","..."
|
|
},
|
|
|
|
-- call variant (shifted timing)
|
|
{
|
|
"...","G-4","...","A-4","...","C-5","...","A-4",
|
|
"...","...","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- response variant
|
|
{
|
|
"...","E-4","...","F-4","...","G-4","...","F-4",
|
|
"D-4","...","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- dense DDR-ish alternating
|
|
{
|
|
"C-5","...","D-5","...","C-5","...","D-5","...",
|
|
"E-5","...","F-5","...","E-5","...","...","..."
|
|
},
|
|
|
|
-- higher variation arpeggio
|
|
{
|
|
"G-5","...","B-5","...","D-6","...","G-6","...",
|
|
"D-6","...","B-5","...","G-5","...","...","..."
|
|
},
|
|
|
|
-- low groove pattern
|
|
{
|
|
"C-3","...","C-4","...","G-3","...","C-4","...",
|
|
"F-3","...","C-4","...","...","...","...","..."
|
|
},
|
|
|
|
-- slightly chaotic (good for branching)
|
|
{
|
|
"C-5","...","E-5","D-5","...","G-5","...","F-5",
|
|
"...","D-5","...","C-5","...","...","...","..."
|
|
},
|
|
|
|
-- mixed density
|
|
{
|
|
"C-5","D-5","...","E-5","...","F-5","G-5","...",
|
|
"E-5","...","D-5","C-5","...","...","...","..."
|
|
},
|
|
|
|
-- offset staircase up
|
|
{
|
|
"...","C-4","D-4","E-4","F-4","G-4","A-4","B-4",
|
|
"C-5","...","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- offset staircase down
|
|
{
|
|
"...","C-5","B-4","A-4","G-4","F-4","E-4","D-4",
|
|
"C-4","...","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- dense zigzag
|
|
{
|
|
"C-5","E-5","D-5","F-5","E-5","G-5","F-5","A-5",
|
|
"G-5","...","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- jack pattern (DDR classic)
|
|
{
|
|
"C-5","C-5","C-5","...","C-5","C-5","...","...",
|
|
"D-5","D-5","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- alternating two-note burst
|
|
{
|
|
"C-5","D-5","C-5","D-5","C-5","D-5","...","...",
|
|
"E-5","F-5","E-5","F-5","...","...","...","..."
|
|
},
|
|
|
|
-- wide jumps
|
|
{
|
|
"C-4","...","G-5","...","D-4","...","A-5","...",
|
|
"E-4","...","B-5","...","...","...","...","..."
|
|
},
|
|
|
|
-- rolling triplet-ish
|
|
{
|
|
"C-5","E-5","G-5","...","E-5","C-5","E-5","...",
|
|
"G-5","...","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- syncopated dense
|
|
{
|
|
"...","C-5","D-5","...","E-5","...","F-5","G-5",
|
|
"...","E-5","...","C-5","...","...","...","..."
|
|
},
|
|
|
|
-- mirrored pattern
|
|
{
|
|
"C-5","D-5","E-5","F-5","E-5","D-5","C-5","...",
|
|
"...","...","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- chord-outline arpeggio feel
|
|
{
|
|
"C-4","...","G-4","...","E-5","...","G-4","...",
|
|
"C-4","...","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- broken rhythm variant
|
|
{
|
|
"C-5","...","D-5","E-5","...","F-5","...","G-5",
|
|
"E-5","...","D-5","...","C-5","...","...","..."
|
|
},
|
|
|
|
-- fast burst then rest
|
|
{
|
|
"C-5","D-5","E-5","F-5","G-5","A-5","...","...",
|
|
"...","...","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- low-high bounce fast
|
|
{
|
|
"C-3","C-5","C-3","C-5","C-3","C-5","...","...",
|
|
"G-3","G-5","G-3","G-5","...","...","...","..."
|
|
},
|
|
|
|
-- repeated with shift
|
|
{
|
|
"...","E-5","...","E-5","...","E-5","...","...",
|
|
"D-5","...","C-5","...","...","...","...","..."
|
|
},
|
|
|
|
-- clustered mid
|
|
{
|
|
"D-5","E-5","F-5","...","E-5","D-5","C-5","...",
|
|
"D-5","...","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- broken descending
|
|
{
|
|
"C-6","...","A-5","...","F-5","...","D-5","...",
|
|
"C-5","...","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- chaotic jumpy (important for branching)
|
|
{
|
|
"C-5","...","F-5","D-5","...","A-5","...","E-5",
|
|
"...","G-5","...","C-5","...","...","...","..."
|
|
},
|
|
|
|
-- double-step pattern
|
|
{
|
|
"C-5","D-5","D-5","E-5","E-5","F-5","...","...",
|
|
"G-5","...","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- uneven spacing
|
|
{
|
|
"C-5","...","...","D-5","E-5","...","...","F-5",
|
|
"G-5","...","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- fast alternating high
|
|
{
|
|
"G-5","A-5","G-5","A-5","G-5","A-5","...","...",
|
|
"F-5","E-5","...","...","...","...","...","..."
|
|
},
|
|
|
|
-- low groove with variation
|
|
{
|
|
"C-3","...","C-4","...","G-3","...","D-4","...",
|
|
"F-3","...","C-4","...","...","...","...","..."
|
|
},
|
|
|
|
-- semi-random filler (very useful)
|
|
{
|
|
"C-5","...","E-5","...","D-5","...","G-5","...",
|
|
"F-5","...","A-5","...","E-5","...","...","..."
|
|
},
|
|
|
|
-- near-repetition (state collision booster)
|
|
{
|
|
"C-5","...","D-5","...","E-5","...","C-5","...",
|
|
"D-5","...","E-5","...","C-5","...","...","..."
|
|
},
|
|
|
|
-- same but shifted (VERY important)
|
|
{
|
|
"...","C-5","...","D-5","...","E-5","...","C-5",
|
|
"...","D-5","...","E-5","...","C-5","...","..."
|
|
},
|
|
|
|
}
|
|
|
|
local model = build_markov_model(flatten(training_data), 2)
|
|
|
|
print(inspect(model))
|
|
|
|
--[[
|
|
local generated = generate_sequence(model, 100)
|
|
|
|
for i,v in ipairs(generated) do
|
|
print(v)
|
|
end
|
|
--]]
|