Sorry for the late reply.
Found the problem now. The Lua garbage collector destroys the line references at a point where it should not. This actually has nothing to do with the pattern line notifier. It just makes the garbage collector run more often, because more stuff happens (more Lua objects are created).
This is also the reason why this error only pops up randomly: The garbage collector runs, when not called explicitly, every now and then, or not. Is not really predictable unless called explicitly.
Here is a way to replicate the problem every time:
local note_column = renoise.song().patterns[1].tracks[1].lines[1].note_columns[1]
collectgarbage()
note_column.instrument_value = 4 -- -> will fire an error
Will need a bit of time to see how we can solve this. What happens internally here is that:
local note_column = renoise.song().patterns[1].tracks[1].lines[1].note_columns[1]
creates a temporary “line” object, which is no longer referenced anywhere, thus it is marked to be collected.
But the line object is still referenced internally by the “note_column” object. So as soon as the line gets collected, the column gets invalid too and will fire an error when accessed.
You can solve, hackaround, the problem for now via:
-- keep the line object referenced, avoid that it is being collected during the function call:
local line = renoise.song().patterns[1].tracks[1].lines[1]
local note_column = line .note_columns[1]
note_column.note_value = math.random(48)
collectgarbage()
note_column.instrument_value = 4 -- -> should never fire an error now
This has nothing to do with the error, but I wondered why you don’t use the “pos” in your “function handle_line_notifier(pos)”, but use the selected track and pattern there instead to query the changed line.
Lines do not necessarily change at the “selected” position in Renoise. You can clear a whole pattern, or undo/redo inserting, deleting them somewhere in the song. Aka, you can also edit notes that are !not! under the cursor.
To access the changed line in the notifier, instead of the line under the cursor, you can do this instead:
function handle_line_notifier(pos)
-- can also use the functions track(),pattern() instead of the table
-- accessors tracks[], patterns[] to speed up things. The tables create
-- tons of temporary objects we are not interested in
local line = renoise.song():pattern(pos.pattern):track(pos.track):line(pos.line)
print(("line at pos:%d,%d,%d changed to:"):format(pos.pattern, pos.track, pos.line))
print(line)
end