Work in progress: Piano roll

noteTone = {}
noteLength = {}
noteLine = {}
noteColumn = {}
		
lineValues = song.selected_pattern.tracks[trackId].lines
		
local columns = song.tracks[trackId].visible_note_columns

for c = 1, columns do
for s = 1, steps do
local note = lineValues[s].note_columns[c].note_value
if note < 120 then --120 is off, 121 is empty
table.insert(noteTone, note)
table.insert(noteLine, s)
table.insert(noteColumn, c)
end
end	
end

For accessing some song values there is a faster way than the standard table indexing:

-- Access to a single line by index. Line must be [1-MAX_NUMBER_OF_LINES]).
-- This is a !lot! more efficient than calling the property: lines[index] to
-- randomly access lines.
renoise.song().patterns[].tracks[]:line(index)
 -> [renoise.PatternLine]

It is a method call so it uses the colon operator and curved parenthesis. You also lose the s , so

tracks becomes :track ()

lines becomes :line ()

columns becomes :column ()

etc.

So for your code above it becomes:

(see changes lines 7,9,13)

noteTone = {}
    noteLength = {}
    noteLine = {}
    noteColumn = {}
    
    lineValues = song.selected_pattern:track(trackId).lines --.tracks[] changed to :track() method
    
    local columns = song:track(trackId).visible_note_columns --.tracks[] changed to :track() method

    for c = 1, columns do
      for s = 1, steps do
        local note = lineValues[s]:note_column(c).note_value --.note_columns[] changed to :column() method
        
        if note < 120 then --120 is off, 121 is empty
          table.insert(noteTone, note)
          table.insert(noteLine, s)
          table.insert(noteColumn, c)
        end
      end  
    end

Should add some speed boost.

1 Like

Should add some speed boost.

Sorry, it didn’t help, but thanks. I’ll use this method just in case.

1 Like
  1. Here is another optimization, maybe not massive in most cases, but worth using as a rule IMO. table.insert is a table access in itself, which can be ‘cached’ (localized).
local table_insert = table.insert

for c = 1, columns do
 for s = 1, steps do
 local note = lineValues[s]:note_column(c).note_value --.note_columns[] changed to :column() method
 
 if note < 120 then --120 is off, 121 is empty
  table_insert(noteTone, note)
  table_insert(noteLine, s)
  table_insert(noteColumn, c)
 end
 end 
end
  1. Are you sure that this section is the culprit?

You are iterating 12 note columns, which is pretty heavy. There is a scheme that can be used to optimize this a lot, by using string functions on tostring(line) to extract the note values - thereby reducing the song() access to one access per line.

Sorry, it didn’t help, but thanks. I’ll use this method just in case.

Definitely worth doing as a rule in scripts, a shame it didn`t make much difference here though.

  1. Are you sure that this section is the culprit?

You are iterating 12 note columns, which is pretty heavy. There is a scheme that can be used to optimize this a lot, by using string functions on tostring(line) to extract the note values - thereby reducing the song() access to one access per line.

Hey joule, I`m just finally getting around to looking at your optimization stuff (and your mods to my Set Track Widths To Active Columns tool :blush: , better late than never eh :yeah: )

Maybe I`ll try and translate the method to a working example here…

  1. Are you sure that this section is the culprit?

Yes, I checked

You are iterating 12 note columns, which is pretty heavy. There is a scheme that can be used to optimize this a lot, by using string functions on tostring(line) to extract the note values - thereby reducing the song() access to one access per line.

Why 12?

As for ‘tostring’, are you sure that it is faster to get key, sign and octave from string and then transform them to number?

Why 12?

As for ‘tostring’, are you sure that it is faster to get key, sign and octave from string and then transform them to number?

My mistake. I didn’t notice that you don’t iterate all columns.

Yes, As soon as you’re iterating more than one column, there is a way to do it faster with string.sub et c.

EDIT: an example can be seen in this tool: https://forum.renoise.com/t/new-tool-2-7-3-1-set-track-width-to-active-columns/31078

PS. Btw, I just remembered… if you’re creating an indexed table, it’s even faster to do something like “table[#table+1] = new_value” instead of using table.insert.

Amazing :slight_smile:

  1. Are you sure that this section is the culprit?

Wow, you was right in your suspicions. And I was right before, when I thought that the problem is in XYpad.

In fact, there is no lag at all when “mouse warping” is enabled in preferences.

But, when it’s turned on, mouse cursor jumps to snapback position on button release

(Are you getting “too many updates”? I guess you’ll have to filter it all to only make a ‘big bang’ on relevant changes)

There was also a quirk when it comes to snapback that it will bang the value observable two times (for x and y). You’ll probably have to make some “timer gate” there to optimize that.

I’ve made changes, so track cells are not itterated when note is dragged, and I’m filtering first and last value of xypad. But it isn’t what mattered. Enabling “mouse warping” removed lag. But now

mouse cursor jumps to snapback position on button release

How to deal with this? I don’t suppose that cursor can be controlled from code

Nope…

My experience is that mouse warping has to be off for the xypad exploit to work. My mouse cursor moves horribly slow otherwise. There is some cause to the lag that you need to fix (mouse warping on is not a good solution). It’s difficult to guess the cause…

(Does the value_observable bang differently depending on mouse warp setting? It shouldn’t IMO… do a bit of print ‘debugging’ to compare what’s happening on and off respectively)

My experience is that mouse warping has to be off for the xypad exploit to work.

But it is on by default. So it is most common state. Are you tablet user?

Does the value_observable bang differently depending on mouse warp setting? It shouldn’t IMO

It doesn’t.

Yeah, but it doesn’t work very well with xypad and normal mouse if it’s on. And the snapback becomes an issue. Must be off…

It was writing to track, not reading, that slowed down dragging. If writing only to ‘note_value’ it’s not that bad, but when ‘instrument_value’ also - too laggy.

So, I placed “timer gate” as you say and everything is ok. Too easy.

Shame, that it took so much time.

Wow. Amazing.

The closest thing I’ve seen before this thread is a QT/C++ app that did piano roll over OSC by a user named Re.Dread (?) I spent the last 30 minutes looking for the topic where his tool was discussed, with screenshots, and failed. Deleted? I did find the GitHub repo: [https://github.com/dmin7/Qtroll ] The protoype was named re.dread.Qtroll.xrnx

Keep up the awesome work.

@frenetic_friend

Was never fond of the idea of a Piano Roll inside Renoise, but as you’ve done it anyway, and others are liking the idea, here’s a suggestion (an important one).

Go vertical … I mean why are you using a horizontal scroller when Renoise is vertical by design?

Just because other DAW’s do it that way doesn’t mean you have to use the same bad design. Be inventive and make it ‘belong’ Renoise by making it a vertical Piano Roll to match the vertical tracker aspect of Renoise. Making it a vertical Piano Roll is not only better from a design integration aspect, it’s simply better by design cause it’s the right way up! Think about it, those horizontal Piano Rolls in the other DAWs are wrong, they are all wrong, because they all suffer from having the keyboard displayed on it’s side. Make a vertical Piano Roll, however, and that nonsese is removed cause it means you can have the keyboard the right way up, positioned at the bottom of the Piano Roll where it should be. It means you can line-up the notes scrolling from the top of all the keys, black or white, and all the right way up!

So personally, congrats and well done on for what you’ve achieved, but zero points for making the same mistake they all make.

Renoise is vertical by design, so it makes sense to take advantage of that and have a superior vertical Piano Roll.

I believe that the reason of the pianorroll done in vertical is to have the landscape view of the composition, because the monitors are wider than tall.On the other hand, there has always been the mania of making the pianoroll upright. The same for patterns view (the work area is horizontal).But the pianorroll horizontally (work area in vertical) would work very well with Renoise, for a concordance with the pattern editor.Will you also say that Renoise’s automation editor is badly made?

That being said, I have no problem with seeing things vertically or horizontally.My brain is accustomed to both situations. However, one tool may be designed to offer both UI, in vertical and horizontal.It is enough to design it for both cases and to add a button that says “rollover”, or “vertical” / “horizontal”.I suppose the programmer will be interested in leaving his tool stable. These are secondary things that can be added later;in this case, it is necessary to think to “leave it ready” for later.

The main problem with this tool is that it may take up a lot of horizontal space, and if you use only one monitor, you will have trouble seeing the pattern editor along with the tool at the same time.

I have been using a tool that has two virtual pianos, one horizontal and one vertical, by design theme / need, and there is no problem.Creating the GUI is not the most complicated. The difficult thing is that everything works as you would expect.

By the way, here is an example of building a horizontal piano. The same method can be used to construct it vertically:https://forum.renoise.com/t/build-a-perfect-virtual-piano-using-buttons-only/47819

The piano roll brainstorming thread isover here people.

Unless you got code, let this person work on their cool project, possibly raising the bar for Renoise Lua, without harshing the vibe?

Wasn’t aware of the other thread, and I wasn’t “harshing the vibe”, either.

It’s just a suggestion, and I suggested it cause just about every DAW designer out there is completely clueless about design and cannot think for themselves (which is why they all suffer from horizontal piano rolls). It has nothing to do with the aspect of the screen, and everything to do with the designer not being able to design and think on their own (AKA people doing a job they actually have no clue about). You cannot fit a complete horizontal composition in view no more than you can fit a complete vertical one in view, so I’m afraid any percieved benefit of horizontal piano rolls is complete nonsense. The reason for the suggestion now, is that it’s at an early stage, so better to suggest it now than at a later time.

It was a suggestion, not an order, so no need to “harsh the vibe” like you just did, and no, I don’t have any code cause I’m not a coder.

I do, however, have design skills that make so-called “professionals” look like complete amateurs (which most of them are).

A couple of comments.You are not the first to make suggestions or ideas in this thread.That’s what I understood.I do not think anything will happen to you comment but it is not necessary to score.And but…

But,When a “newborn programmer” makes a program, he is trying to build things, not make the perfect mega tool.

Frenetic_friend (in this case) is building a very complex tool, not thinking in vertical or horizontal, because seen in perspective, it “is stupid” at this point in the game (is a secondary theme).The important thing is to create the tool and that it works!Then we’ll see (he will see…).In fact, this programmer has proven more than many of us together, since his tool brings together things so complex that only you understand if you know something of the code used.

Regarding the pianorroll link. It’s just an topic since 2002/2003. That gives to think.It is the first time that I see a real pianorroll tool.And for construction, I assure you that the programmer has thought much more than you can get to understand without knowing code.

And yes, the way to design also has to do with the shape of the monitor or what you also want to add to the tool.Most things have a reason, or several, are not done without thinking.

I didn’t choose horizontal work area because I’ve never seen different approach. Before starting to make this tool I tried Radium Music Tracker, where piano roll and automation curves are located along each track in pattern view.

Plus, I saw a topic here with vertical concept. But I wanted my tool to be more traditional. And as Raul said, there is more horizontal space, and automation editor is horizontal too.

you will have trouble seeing the pattern editor along with the tool at the same time.

Do you really need to see them both? In any case, the tool is resizeable. 2 octaves can fit under pattern editor in place of automation pane.

I have been using a tool that has two virtual pianos, one horizontal and one vertical

I wonder what tool was that.

However, one tool may be designed to offer both UI, in vertical and horizontal

Yes, maybe later I’ll implement it.