I did this. I will change it when the API change, but it is not that complicated (once it is done …)
I did not see a LUA API to read/write the Session Metadata? It would be nice to have a way to save data. I know the script itself is saved with the session, but as the API will change, the scripts will need to be refreshed.
Also, it would be super helpful to have auto-completion in VS-Code and others, I guess there should be some standard definition file for classes, functions …
ardour {
["type"] = "EditorAction", -- "DSP", "Session", "EditorHook", "EditorAction"
name = "Create Song Markers",
-- Optional
author = "Bruno VERNAY",
license = "MIT",
description = [[Structure the song with ranges: Verse ; Chorus ; Break ...
Currently, the song structure is defined in the script
Could add a dialog box to enter the structure
Could parse the Session:Metadata description structure if available in Lua
]]
}
function factory (unused_params)
return function ()
local prefix = "S| " -- Name prefix for the ranges
local offset = 1 -- Measure 1 is the very first (Not 0!)
local song = { -- Adapt to your song { Part name, Number of measures }
{ "Intro", 4 },
{ "A 1", 8 },
{ "B 1", 12 },
{ "A 2", 8 },
{ "B 2", 12 },
{ "Outro", 4 },
}
function bbtToPos(bar, beat, tick)
local bfc = ARDOUR.DoubleBeatsSamplesConverter(Session:tempo_map(), 0)
local calcBeat = ((bar - 1) * 4) + (beat - 1) + (tick / 1920)
return bfc:to(calcBeat)
end
--- Create a range.
-- @param name Range name
-- @param start Measure number where to start the range (offset)
-- @param length Range size in measures
-- @return The last measure number (to be used as next offset)
function create(name, start, length)
assert( start > 0, "Measures start at 1!")
local rng = Session:locations():add_range(bbtToPos(start,1,0), bbtToPos(start+length,1,0))
rng:set_name(prefix .. name)
-- Should be Glue to the beat
-- Should be locked?
return start+length
end
-- is there a logger or something?
print(" * - * Create Song Markers * - * ")
print(" Clean up ") -- Remove previous ranges starting with "prefix ..."
for l in Session:locations():list():iter() do
-- l:is_mark()
if l:is_range_marker() and string.find (l:name(), "^" .. prefix .. "*") then
print("Removing previous range: ", l:name())
Session:locations():remove(l)
end
end
print("Song structure:")
print(" # ; Start ; Length ; Name")
for i,v in ipairs(song) do
print(string.format(" %2d ; %4d ; %2d ;\t%s", i, offset, v[2], prefix .. v[1]))
offset = create(v[1], offset, v[2])
end
end
end
Since I keep simplifying and improving, check the latest version here: lua · master · Bruno Vernay / Ardour-utils · GitLab