I also took a quick look. Raul - I have to say, for a realtime script, you are actually being quite wasteful…
if song:pattern( spi ):track( sti ):line( stpl ):note_column( 1 ).note_string ~= '---' then
-- do something
end
if song:pattern( spi ):track( sti ):line( stpl ):note_column( 1 ).note_string == 'OFF' then
-- do something
end
-- etc...
There is nothing “wrong” here per se, but several things you can do better.
As per my third advice in the lua optimization thread, it’s good idea to store references to objects that you are going to call repeatedly.
First of all, it’s very simple to avoid several function calls by storing a reference to the line you’re working on:
local ln = song:pattern( spi ):track( sti ):line( stpl )
This way, you avoid the three API functions you are calling - pattern(), track() and line() - each time you need to access a note column.
And since you are using the line above a total of 48 times, this is 48*3 == 144 function calls avoided, with one simple change.
It makes the code a lot easier to read too
Another improvement is to use the if … else syntax to simplify comparisons:
if (ln:note_column( 1 ).note_string ~= '---') then
-- do something
elseif (ln:note_column( 1 ).note_string == 'OFF') then
-- do something else
end
Or better still, using the previous technique and storing a reference to the note-column (additionalcalls avoided)
local col = ln:note_column( 1 )
if (col.note_string ~= '---') then
-- do something
elseif (col.note_string == 'OFF') then
-- do something else
end
Using if…else is more efficient, since the second statement - looking for the (“OFF”) - will never be evaluated if the first part was found to be true.
Now, with such a simple example there might not be a big impact. But imagine that your code was more complex than this? Skipping parts as early as possible can be a HUGE performance booster.
And both are general principles which can be applied to any programminglanguage
Also remember that you don’t want overruns, so whatever buffering/caching system you come up with (including button/text rendering, because at the moment you have all of that gui changing stuff executed in your timer function) it has got to complete in less time than the time you set your periodic timer (which at the moment from your code is set at 5ms. I assume you are not planning on running this on a 33MHz 486 then )
I never used the timer, so I don’t have much experience with that.To me, idle_notifier is the natural choice, as it simply runs when Renoise has time for it.