Lua Scripting: access sources list

Hi all

I am trying to write a lua script to help me distribute imported audio files to tracks. However, I can’t figure out how I could access the list of imported sources via the Session or Editor objects. Is it even exposed via the Lua API?

At The Ardour Manual I see functions to access tracks, regions, locations, etc. but nothing to get to the sources list. All I can see is the Session:source_by_id(id) function, but I would not know how to get to the ID of a specific source, and what I really need is a way to iterate over all imported sources.

Thanks a lot,
Dominik

Good day,

After a sufficient view of your concern, you don’t need a script at all to distribute imported audio files to different tracks.

Import desired audio files to “To Source List”

and drag the desired file to your desired track with the mouse.

That’s quite a relief. Try it.

Hi Thomas

Not sure whether you’re serious, but of course I am aware how to do it manually :slight_smile: However, I’d like to automate that process.

I am often mixing my band’s tracks, for example from rehearsal sessions. Our digital mixer records directly to a USB drive, which I then take home and import the audio files from into Ardour.

I have a session template with all the tracks, routing, plugins etc. I then drag and drop the imported files to their respective track. The audio files always have the same names, as do the tracks in Ardour (ie. “Lead Guitar”, “[Vocalist’s Name]”, “Snare”, etc. Since this process is always the same, it seems to be something that should be trivial to automate.

All I’m missing from the Lua API is a way to access the list of imported tracks, ie. what’s visible in the “Sources” window (“Quellen” in your second screenshot).

Maybe there is another way to automate this while importing, which I’m not aware of. I don’t want to import the files into new tracks since I would then need to setup routing, plugins, etc all over again.

Regards,
Dominik

For what it’s worth, I managed to do what I want by importing the audio files into a single new track (ie. as a sequence). When selecting the regions in this “temporary track” I get access to them via Editor:get_selection().regions:regionlist(), and then clone them into the correct tracks (ARDOUR.RegionFactory.clone_region(…)). That’s good enough for me :slight_smile:

Hello Dominic,

You record the music played by your music band on a USB drive via the digital mixer.

At home you want to import all the recorded sounds into the Ardour project with one click using a LUA script and make them available in the respective tracks. This will be a difficult but solvable task for a programmer.

You could have it easier and more efficiently. How about using a laptop instead of the USB drive and recording the band’s music with Ardour right away? So you could drag and drop the whole Ardour project from your laptop to your home computer. The Ardour project would always be operational. A LUA script would no longer be necessary.

Hi Thomas

I appreciate your feedback. Yes, using a laptop would work as well, but it would mean I would need to carry more things to rehearsal and back. The solution with the USB drive works well enough for me :slight_smile:

As mentioned in my previous comment, I was able to solve my problem by just importing all the files into a single track (ie. choosing the “sequence” option in the import dialog) and then distributing the regions from the selected track. Here’s the (slightly adapted) script in case anyone else needs something similar:

ardour {
  ["type"] = "EditorAction",
  name = "Distribute regions to tracks"
}

function factory () return function ()

  	-- map file names to track names, adapt to your own needs
  	local track_mapping = {
		  ["03"] = "Vox",
		  ["04"] = "Guitar",
		  ["05"] = "Snare",
                  -- ...
 	}

	---find the target track for a region
	function track_for_region(region)
		-- Region names are something like "03 - VOX ...", "04 - GUITAR ..." and so on, ie. they all start
		-- with a 2 digit number. We use this to retrieve the target track name from the track_mapping table.
		local index = region:name():sub(0, 2)
		print(index)
		local target_track_name = track_mapping[index]

		if target_track_name then

			print("target track name: " .. target_track_name)

			local target_track = nil
			for t in Session:get_tracks():iter() do
				if t:name() == target_track_name then
					target_track = t
					break
				end
			end

			if target_track then return target_track:to_track() end
		end
	end

	---
	---calculate the position where to insert the region in the playlist
	---
	---We either insert it at the end of the last region, or at the beginning if there
	---are no regions in the playlist
	function get_region_insertion_position(playlist)
		local position = 0
		for r in playlist:region_list():iter() do
			position = math.max(position, r:position() + r:length())
		end
		return position
	end


	function set_session_end(position)
		for l in Session:locations():list():iter() do
			if l:name() == "session" then
				l:set_end(position, false, false, 0)
			end
		end
	end


	-- main starts here
	--
	-- get the selected track, loop over its regions, and move them
	-- to the correct track
	--
	local sel = Editor:get_selection()

	local session_end = 0

	for t in sel.tracks:routelist():iter() do
		local source_track = t:to_track()
		if source_track:isnil() then goto next_track end 
		
		local playlist = source_track:playlist()
		local region_list = playlist:region_list()

		for region in region_list:iter() do
			print(region:name())
			local target_track = track_for_region(region)

			if target_track then
				print(target_track)

				local target_playlist = target_track:playlist()
				print(target_playlist)

				local position = get_region_insertion_position(target_playlist)
				print("position: " .. position)

				-- clone region and at it to the target track's playlist
				local new_region = ARDOUR.RegionFactory.clone_region(region, true, true) -- not sure what these booleans mean
			                                                              		         -- but it seems to work
				print(new_region)
				target_playlist:add_region(new_region, position, 1, false, 0, 0, false) -- again not sure about some of these arguments
				session_end = math.max(session_end, new_region:position() + new_region:length())

				playlist:remove_region(region)
			end
		end
		::next_track::

		-- TODO delete source track if all regions moved ...
	end

	if session_end > 0 then
		set_session_end(session_end)
	end

end end