New Tool (3.1) SuperNudge

This tool simplifies moving column entries (notes and effects) up and down in the Pattern Editor. Notes can be moved up/down either by 1 step or by 1 line. Effects can be moved up/down by 1 line.

com.pandabot.SuperNudge.xrnx (5.5 KB)

10 Likes

Welcome to the forum and thanks for the script!

Nice work, dude :slight_smile:

It’s funny because I have an almost identical tool that I’ve been tinkering with for ages, just sitting in my own private unfinished scripts collection.

Points for using Death Grips in the video. Hope it doesn’t get flagged for copyright, but I haven’t heard this remix before. One of your own?

Shameless plug of my own unfinished Guillotine remix that I was messing with years ago: soundcloud)

1 Like

Thanks man :smiley:

I took it from here:

Regarding the slow performance you mention in the video, I did take a quick look at your code but it’s a bit difficult to track down exactly where some of the bottlenecks might be, simply due to how fractured everything is and broken down into multiple functions across multiple files.

Certainly not a bad way to work necessarily, but it does make debugging a little bit trickier.

I do feel like there probably are a few places where you can trim off some of the fat, though, to improve performance a bit.

For example, in matrix.lua populateMatrixForMovingDown() you have the following line nested within a loop:

local noteColumn = pattern.tracks[trackIndex].lines[lineIndex]:note_column(columnIndex)

Right off the bat, the [] table-based accessors will always be a bit slower than the () function-based accessors, so this change should immediately perform better:

local noteColumn = pattern:track(trackIndex):line(lineIndex):note_column(columnIndex)

Going a bit further, repeatedly looking up the same properties within loops can be improved by taking local references outside of the loop instead, so this:

for lineIndex = selection.start_line, lastIndex do
  for trackIndex = selection.start_track, selection.end_track do
    for columnIndex = firstColumn(trackIndex), lastColumn(trackIndex) do
      if isNoteColumn(trackIndex, columnIndex) then
        local noteColumn = pattern.tracks[trackIndex].lines[lineIndex]:note_column(columnIndex)
...

Could be rearranged slightly and improved like so:

for trackIndex = selection.start_track, selection.end_track do
  local track = pattern:track(trackIndex)
  for lineIndex = selection.start_line, lastIndex do
    local line = track:line(lineIndex)
    for columnIndex = firstColumn(trackIndex), lastColumn(trackIndex) do
      if isNoteColumn(trackIndex, columnIndex) then
        local noteColumn = line:note_column(columnIndex)
...

Further still, several things like the first and last columns are being repeatedly checked within the line loop, even though those properties should never change within that context, so we can avoid even more unnecessary lookups here…

for trackIndex = selection.start_track, selection.end_track do
  local track = pattern:track(trackIndex)
  local firstCol = firstColumn(trackIndex)
  local lastCol = lastColumn(trackIndex)
  for columnIndex = firstCol, lastCol do
    if isNoteColumn(trackIndex, columnIndex) then
      for lineIndex = selection.start_line, lastIndex do
        local line = track:line(lineIndex)
        local noteColumn = line:note_column(columnIndex)
...

And so on…

I haven’t actually tried to implement those changes in your code, but hopefully you understand the basic premise behind what I’m getting at.

Can you add support for phrases, too?

1 Like

@ffx ┌ಠ_ಠ)┌∩┐ ᶠᶸᶜᵏᵧₒᵤ

No jk yeah that’s a good idea, I should. However unfortunately it doesn’t seem possible to get the position of the Edit Cursor from the api, so that’s really preventing me from using the Phrase Editor seriously. I put in a request here https://forum.renoise.com/t/the-api-wishlist-thread/29285

@dblue whoa it’s much faster now! I implemented some of your improvements and updated the attachment above

whoa it’s much faster now!

I just gave the new version a quick try and it’s noticeably faster indeed!

Quite surprising what a few simple tweaks can do, eh? :slight_smile:

Glad I could help in some way.

Cheers.

@ffx ┌ಠ_ಠ)┌∩┐ ᶠᶸᶜᵏᵧₒᵤ

No jk yeah that’s a good idea, I should. However unfortunately it doesn’t seem possible to get the position of the Edit Cursor from the api, so that’s really preventing me from using the Phrase Editor seriously. I put in a request here https://forum.renoise.com/t/the-api-wishlist-thread/29285

Yeah pandabot, fuck you, too, very kindly. You funny asshole :slight_smile:

1 Like

just to remind myself how awesome this tool is - allowing us to bind delay column nudge! :slight_smile: Cheers & thanks @pandabot

3 Likes

So this is awesome but doesn’t seem to work on the first step of a pattern, or am I missing something?

edit: oh it’s cause there was a note after it lol :slight_smile:

Does anyone know if this tool works on Renoise 3.4.3?

Is this possible to make it work in the phrase editor as well?

API limitations make it impossible. there’s not enough control over phrases in the API, unfortunately. maybe later?