You can create a small helper function to get the track index, by using “rawequal” to compare a track object with renoise.song().tracks. “rawequal” bypasses the object’s comparison operator (which in most cases is not defined anway), and tests object identity instead:
function get_track_index(_track)
assert(_track, "expected a valid track object")
for index, track in ipairs(renoise.song().tracks) do
if (rawequal(track, _track)) then
return index
end
end
end
-- test
assert(get_track_index(renoise.song().tracks[2]) == 2)
assert(get_track_index(renoise.song().selected_track) == renoise.song().selected_track_index)
A sneaky way (just for fun): Classes in the renoise API are not read-only. So one can define new member functions for existing renoise.* classes, or replace existing ones.
One can also wrap a getter/setter function pair to define new properties this way. This is done with the global function “property()”:
property(getter, setter) takes a getter and setter (optional) function as parameter. Every time a property gets read, the getter function is called and it’s return value will be put on the stack. Every time you assign the property, the setter function is called with the given argument. The first argument of the passed functions will always be “self”.
In the example below, this is used to create a new “track_index” property to renoise.Track and GroupTrack. Because only a getter is present, assignment is disallowed too and will fire an error, which is exactly what we want.
-- Inject a new property "track_index" into the renoise.[Group]Track class.
-- Define this as early as possible in your script to make the property
-- as early as possible available. Once it's defined, the property will be
-- available for every existing and new object of type "renoise.[Group]Track",
-- so you don't have to define this for every new track that gets created
-- within Renoise.
local track_index_property = property(function(self)
for index, track in ipairs(renoise.song().tracks) do
if (rawequal(self, track)) then
return index
end
end
end)
-- and apply it to all track classes in the API
renoise.Track.track_index = track_index_property
renoise.GroupTrack.track_index = track_index_property
-- test
assert(renoise.song().tracks[6].track_index, 6)
assert(renoise.song().selected_track.track_index, renoise.song().selected_track_index)
-- assignment is not allowed (track_index is read-only)
assert(pcall(function() renoise.song().tracks[2].track_index = 23 end) == false)
Same thing could be done to create a “member_index” for tracks in groups of whatever else you need.
Oh and all this of course is not a lame excuse. track_index should be available by default in the API.