Advertisement
Guest User

Ardour multi-track import

a guest
Apr 23rd, 2018
238
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.18 KB | None | 0 0
  1. ardour {
  2.     ["type"] = "EditorAction",
  3.     name = "POOLS Rehearsal Mix",
  4.     author = "Robert Schneider (robert.schneider@aramar.de)",
  5.     description = [[
  6.     v1.0.1
  7. This template helps create the tracks for POOLS rehearsal recording.
  8.  
  9. This script is developed in Lua, and can be duplicated and/or modified to meet your needs.
  10.  
  11. Now with normalization.
  12. ]]
  13. }
  14.  
  15. function factory(params)
  16.     function session_setup()
  17.         return true
  18.     end
  19.  
  20.     function route_setup()
  21.         return {
  22.             ["Insert_at"] = ARDOUR.PresentationInfo.max_order
  23.         }
  24.     end
  25.  
  26.     -----------------------------------------------------------------
  27.     function basic_serialize(o)
  28.         if type(o) == "number" then
  29.             return tostring(o)
  30.         else
  31.             return string.format("%q", o)
  32.         end
  33.     end
  34.  
  35.     function serialize(name, value)
  36.         local rv = name .. " = "
  37.         collectgarbage()
  38.         if type(value) == "number" or type(value) == "string" or type(value) == "nil" or type(value) == "boolean" then
  39.             return rv .. basic_serialize(value) .. " "
  40.         elseif type(value) == "table" then
  41.             rv = rv .. "{} "
  42.             for k, v in pairs(value) do
  43.                 local fieldname = string.format("%s[%s]", name, basic_serialize(k))
  44.                 rv = rv .. serialize(fieldname, v) .. " "
  45.             end
  46.             return rv
  47.         elseif type(value) == "function" then
  48.             --return rv .. string.format("%q", string.dump(value, true))
  49.             return rv .. "(function)"
  50.         else
  51.             error("cannot serialize a " .. type(value))
  52.         end
  53.     end
  54.  
  55.     function normalize_regions_in_selected_track()
  56.         -- get Editor GUI Selection
  57.         -- http://manual.ardour.org/lua-scripting/class_reference/#ArdourUI:Selection
  58.         local sel = Editor:get_selection()
  59.  
  60.         -- prepare undo operation
  61.         Session:begin_reversible_command("Lua Normalize")
  62.         local add_undo = false -- keep track if something has changed
  63.  
  64.         for route in sel.tracks:routelist():iter() do
  65.             -- consider only tracks
  66.             local track = route:to_track()
  67.             if track:isnil() then
  68.                 goto continue
  69.             end
  70.  
  71.             -- iterate over all regions of the given track
  72.             for region in track:playlist():region_list():iter() do
  73.                 -- test if it's an audio region
  74.                 local ar = region:to_audioregion()
  75.                 if ar:isnil() then
  76.                     goto next
  77.                 end
  78.  
  79.                 local peak = ar:maximum_amplitude(nil)
  80.                 local rms = ar:rms(nil)
  81.  
  82.                 if (peak > 0) then
  83.                     print("Region:", region:name(), "peak:", 20 * math.log(peak) / math.log(10), "dBFS")
  84.                     print("Region:", region:name(), "rms :", 20 * math.log(rms) / math.log(10), "dBFS")
  85.                 else
  86.                     print("Region:", region:name(), " is silent")
  87.                 end
  88.  
  89.                 -- normalize region
  90.                 if (peak > 0) then
  91.                     -- prepare for undo
  92.                     region:to_stateful():clear_changes()
  93.                     -- calculate gain.
  94.                     local f_rms = rms / 10 ^ (.05 * -9) -- -9dBFS/RMS
  95.                     local f_peak = peak -- 0dbFS/peak
  96.                     -- apply gain
  97.                     if (f_rms > f_peak) then
  98.                         print("Region:", region:name(), "RMS  normalized by:", -20 * math.log(f_rms) / math.log(10), "dB")
  99.                         ar:set_scale_amplitude(1 / f_rms)
  100.                     else
  101.                         print("Region:", region:name(), "peak normalized by:", -20 * math.log(f_peak) / math.log(10), "dB")
  102.                         ar:set_scale_amplitude(1 / f_peak)
  103.                     end
  104.                     -- save changes (if any) to undo command
  105.                     if not Session:add_stateful_diff_command(region:to_statefuldestructible()):empty() then
  106.                         add_undo = true
  107.                     end
  108.                 end
  109.                 ::next::
  110.             end
  111.             ::continue::
  112.         end
  113.  
  114.         -- all done. now commit the combined undo operation
  115.         if add_undo then
  116.             -- the 'nil' command here means to use all collected diffs
  117.             Session:commit_reversible_command(nil)
  118.         else
  119.             Session:abort_reversible_command()
  120.         end
  121.     end
  122.     -----------------------------------------------------------------
  123.  
  124.     return function()
  125.         --at session load, params will be empty.  in this case we can do things that we -only- want to do if this is a new session
  126.         if (not params) then
  127.             Editor:set_toggleaction("Rulers", "toggle-tempo-ruler", true)
  128.             Editor:set_toggleaction("Rulers", "toggle-meter-ruler", true)
  129.  
  130.             Editor:access_action("Transport", "primary-clock-bbt")
  131.             Editor:access_action("Transport", "secondary-clock-minsec")
  132.  
  133.             Editor:set_toggleaction("Rulers", "toggle-minsec-ruler", false)
  134.             Editor:set_toggleaction("Rulers", "toggle-timecode-ruler", false)
  135.             Editor:set_toggleaction("Rulers", "toggle-samples-ruler", false)
  136.  
  137.             Editor:set_toggleaction("Rulers", "toggle-bbt-ruler", true)
  138.         end
  139.  
  140.         local p = params or route_setup()
  141.         local insert_at = p["insert_at"] or ARDOUR.PresentationInfo.max_order
  142.  
  143.         --prompt the user for the tracks they'd like to instantiate
  144.         local dialog_options = {
  145.             {
  146.                 type = "folder",
  147.                 key = "folder",
  148.                 title = "Select a Folder",
  149.                 path = "/home/rschneid/tmp/POOLS/USBMTK/Comfortably Numb 1"
  150.             },
  151.             {type = "hseparator", title = "", col = 0, colspan = 3},
  152.             {
  153.                 type = "radio",
  154.                 key = "voxSarah",
  155.                 title = "Sarah",
  156.                 values = {
  157.                     ["Lead"] = 1,
  158.                     ["Background"] = 2,
  159.                     ["Off"] = 3
  160.                 },
  161.                 default = "Lead"
  162.             },
  163.             {
  164.                 type = "radio",
  165.                 key = "voxBasti",
  166.                 title = "Basti",
  167.                 values = {
  168.                     ["Lead"] = 1,
  169.                     ["Background"] = 2,
  170.                     ["Off"] = 3
  171.                 },
  172.                 default = "Background"
  173.             },
  174.             {
  175.                 type = "radio",
  176.                 key = "voxRobert",
  177.                 title = "Robert",
  178.                 values = {
  179.                     ["Lead"] = 1,
  180.                     ["Background"] = 2,
  181.                     ["Off"] = 3
  182.                 },
  183.                 default = "Background"
  184.             },
  185.             {
  186.                 type = "radio",
  187.                 key = "voxPeter",
  188.                 title = "Peter",
  189.                 values = {
  190.                     ["Lead"] = 1,
  191.                     ["Background"] = 2,
  192.                     ["Off"] = 3
  193.                 },
  194.                 default = "Off"
  195.             },
  196.             {type = "hseparator", title = "", col = 0, colspan = 3},
  197.             {type = "checkbox", key = "group", default = true, title = "Group Track(s)?", col = 0},
  198.             {type = "checkbox", key = "normalize", default = true, title = "Normalize Track(s)?", col = 0}
  199.         }
  200.  
  201.         local pools_tracks = {
  202.             --      track name      is a vox?           waves 1 mono, 2 stereo,                     empty on vox
  203.             {name = "Vox Sarah", vox = "voxSarah", wave_files = {"TRK01.WAV"}, template = "", group = "vox"},
  204.             {name = "Vox Basti", vox = "voxBasti", wave_files = {"TRK02.WAV"}, template = "", group = "vox"},
  205.             {name = "Vox Robert", vox = "voxRobert", wave_files = {"TRK03.WAV"}, template = "", group = "vox"},
  206.             {name = "Vox Peter", vox = "voxPeter", wave_files = {"TRK04.WAV"}, template = "", group = "vox"},
  207.             {name = "Bass", vox = "", wave_files = {"TRK07.WAV"}, template = "POOLS Bass", group = "instruments"},
  208.             {name = "Guitar", vox = "", wave_files = {"TRK08.WAV"}, template = "POOLS Guitar", group = "instruments"},
  209.             {name = "Keyboard-L", vox = "", wave_files = {"TRK13.WAV"}, template = "POOLS Keyboard-L", group = "keyboards"},
  210.             {name = "Keyboard-R", vox = "", wave_files = {"TRK14.WAV"}, template = "POOLS Keyboard-R", group = "keyboards"},
  211.             {name = "Bass Drum", vox = "", wave_files = {"TRK09.WAV"}, template = "POOLS Bass Drum", group = "drums"},
  212.             {name = "Snare", vox = "", wave_files = {"TRK10.WAV"}, template = "POOLS Snare", group = "drums"},
  213.             {name = "e-Drums", vox = "", wave_files = {"TRK15.WAV"}, template = "POOLS e-Drums", group = "drums"},
  214.             {name = "Overheads-L", vox = "", wave_files = {"TRK11.WAV"}, template = "POOLS Drum Overheads-L", group = "drums"},
  215.             {name = "Overheads-R", vox = "", wave_files = {"TRK12.WAV"}, template = "POOLS Drum Overheads-R", group = "drums"}
  216.         }
  217.  
  218.         local dlg = LuaDialog.Dialog("POOLS Rehearsal Mix Setup", dialog_options)
  219.         local rv = dlg:run()
  220.         if (not rv) then
  221.             return
  222.         end
  223.  
  224.         -- helper function to reference processors
  225.         function processor(t, s) --takes a track (t) and a string (s) as arguments
  226.             local i = 0
  227.             local proc = t:nth_processor(i)
  228.             repeat
  229.                 if (proc:display_name() == s) then
  230.                     return proc
  231.                 else
  232.                     i = i + 1
  233.                 end
  234.                 proc = t:nth_processor(i)
  235.             until proc:isnil()
  236.         end
  237.  
  238.         function add_lv2_plugin(track, pluginname, position)
  239.             local p = ARDOUR.LuaAPI.new_plugin(Session, pluginname, ARDOUR.PluginType.LV2, "")
  240.             if not p:isnil() then
  241.                 track:add_processor_by_index(p, position, nil, true)
  242.             end
  243.         end
  244.  
  245.         local drum_group, instrument_group, vox_group
  246.  
  247.         if rv["group"] then
  248.             vox_group = Session:new_route_group("Vox")
  249.             vox_group:set_rgba(0x88CC88ff)
  250.             instrument_group = Session:new_route_group("Instruments")
  251.             instrument_group:set_rgba(0x8080FFff)
  252.             keyboard_group = Session:new_route_group("Keyboards")
  253.             keyboard_group:set_rgba(0x80FF80ff)
  254.             drum_group = Session:new_route_group("Drums")
  255.             drum_group:set_rgba(0x801515ff)
  256.         end
  257.  
  258.         local channel_count = 0
  259.  
  260.         for i = 1, #pools_tracks do -- #pools_tracks
  261.             local template_name = pools_tracks[i]["template"]
  262.             if (template_name == "") then
  263.                 local voxmode = rv[pools_tracks[i]["vox"]]
  264.                 print(string.format("voxmode = %d", voxmode))
  265.                 if (voxmode == 1) then
  266.                     template_name = "POOLS Lead Vocals"
  267.                 end
  268.                 if (voxmode == 2) then
  269.                     template_name = "POOLS Background Vocals"
  270.                 end
  271.                 if (voxmode == 3) then
  272.                     template_name = ""
  273.                 end
  274.             end
  275.             print(string.format("template_name = '%s'", template_name))
  276.             if string.len(template_name) >= 1 then
  277.                 template_name = "/home/rschneid/.config/ardour5/route_templates/" .. template_name .. ".template"
  278.                 print(string.format("template_name = '%s'", template_name))
  279.                 local rl =
  280.                     Session:new_route_from_template(
  281.                     1,
  282.                     insert_at,
  283.                     template_name,
  284.                     pools_tracks[i]["name"],
  285.                     ARDOUR.PlaylistDisposition.NewPlaylist
  286.                 )
  287.                 -- fill the track
  288.                 local files = C.StringVector()
  289.                 for f = 1, #pools_tracks[i]["wave_files"] do
  290.                     files:push_back(rv["folder"] .. "/" .. pools_tracks[i]["wave_files"][f])
  291.                 end
  292.                 for route in rl:iter() do
  293.                     Editor:do_import(
  294.                         files,
  295.                         Editing.ImportDistinctFiles,
  296.                         Editing.ImportToTrack,
  297.                         ARDOUR.SrcQuality.SrcBest,
  298.                         ARDOUR.MidiTrackNameSource.SMFTrackName,
  299.                         ARDOUR.MidiTempoMapDisposition.SMFTempoIgnore,
  300.                         -1,
  301.                         ARDOUR.PluginInfo()
  302.                     )
  303.                     if rv["normalize"] then
  304.                         normalize_regions_in_selected_track()
  305.                     end
  306.                     if rv["group"] then
  307.                         if (pools_tracks[i]["group"] == "vox") then
  308.                             vox_group:add(route)
  309.                         end
  310.                         if (pools_tracks[i]["group"] == "instruments") then
  311.                             instrument_group:add(route)
  312.                         end
  313.                         if (pools_tracks[i]["group"] == "keyboards") then
  314.                             keyboard_group:add(route)
  315.                         end
  316.                         if (pools_tracks[i]["group"] == "drums") then
  317.                             drum_group:add(route)
  318.                         end
  319.                     end
  320.                 end
  321.             end
  322.         end
  323.  
  324.         --fit all tracks on the screen
  325.         Editor:access_action("Editor", "fit_all_tracks")
  326.  
  327.         Session:save_state("")
  328.  
  329.         -- determine the number of channels we can record
  330.         local e = Session:engine()
  331.         local _,
  332.             t =
  333.             e:get_backend_ports(
  334.             "",
  335.             ARDOUR.DataType("audio"),
  336.             ARDOUR.PortFlags.IsOutput | ARDOUR.PortFlags.IsPhysical,
  337.             C.StringVector()
  338.         ) -- from the engine's POV readable/capture ports are "outputs"
  339.         local num_inputs = t[4]:size() -- table 't' holds argument references. t[4] is the C.StringVector (return value)
  340.  
  341.         if num_inputs < channel_count then
  342.             -- warn the user if there are less physical inputs than created tracks
  343.             LuaDialog.Message(
  344.                 "Session Creation",
  345.                 "Created more tracks than there are physical inputs on the soundcard",
  346.                 LuaDialog.MessageType.Info,
  347.                 LuaDialog.ButtonType.Close
  348.             ):run()
  349.         end
  350.     end
  351. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement