transpose in pattern matrix

Hello… Is there a way to select a few patterns in the pattern matrix and transpose them?

If you pop up the preferences (Edit -> Preferences) or (Alt comma)…
I may have changed my shortkey to preferences, so it may be different on yours.

Then click on “Keys” and type “transpose” in the search bar, it will narrow it down to “Pattern Editor”,
which means, there is currently no way to select a few patterns in the pattern matrix and transpose them.

Right clicking on areas for the most part will show you the available options as well.

Thanks a lot!

Do you think, it’s possible to add this feature with Lua? I don’t know the Renoise API yet. Is it possible to retrieve the beginning and end of the current selection in the pattern matrix? (as track and song position) Altering the notes in the song is surely possible, isn’t it?

PS: So far I’ve only found renoise.song().sequencer.selection_range but I’m rather looking for something like renoise.song().sequencer.matrix_selection_range, not the order list thing.

Sadly, it’s not so simple, because the PM allows for non-continuous selections. So that means in code you will have to walk through any block that’s selected in PM. But the tool had to do that anyway, so yeah. If you wanna narrow it down to 1 track max, always, then you could suffice with using the selection you’ve just mentioned and make changes to selected track.

Searching for “matrix” in Renoise.Song.API.lua brings zero results. But don’t these tools like GripPie work on selections in the Matrix??? Surely there must be something somewhere… Or is that all done with pattern_slot_mutes_observable? So muting/unmuting rather than just selecting?

You could do something messy for personal use, assuming you never wanted broken selections. Use selection in Sequencer for the patterns you want to operate across, and selection within pattern for getting which tracks to work on. Bit of a mess and probably too complicated to even consider sharing if you were to go this route.

Alternatively you could create empty tracks, drag the matrix cells to those new tracks, transpose track in whole song, drag them back to their original position. Probably easier in the long run…

I’m guessing this one

  
-- Access to sequencer slot selection states.   
renoise.song().sequencer:track_sequence_slot_is_selected(track_index, sequence_index)  
 -> [boolean]  
renoise.song().sequencer:set_track_sequence_slot_is_selected(  
 track_index, sequence_index, selected)  
  

It’s kinda camo

I’ve used the APIs you mentioned and come up with this stuff now… the only problem is, that it’s very slow, it takes over 10 seconds for a 5x5 selection in the matrix. Is there something I could optimize?

  
for order_idx = 1, #renoise.song().sequencer.pattern_sequence do  
 local pattern_idx = renoise.song().sequencer:pattern(order_idx)  
 for track_idx = 1, #renoise.song().tracks do  
 if renoise.song().sequencer:track_sequence_slot_is_selected(track_idx, order_idx) then  
 local track = renoise.song().patterns[pattern_idx].tracks[track_idx]  
 for row = 1, #track.lines do  
 local columns = track.lines[row].note_columns  
 for column_idx = 1, #columns do  
 local column = track.lines[row].note_columns[column_idx]  
 if column.note_value <= 118 then  
 column.note_value = column.note_value + 1  
 end  
 end  
 end  
 end  
 end  
end  
  

" for track_idx = 1, #renoise.song().tracks do "

Here you are treating all tracks now, including the group-, master- and send-tracks.
If you filter upon track types, you may be able to speed it up a tad more.

But if you want to process every notecolumn in every track in the whole song, it will take some time.

It was at some time told to me that there is a significant processing time advance using

  
renoise.song():pattern(pattern_idx)  
  

instead of

  
renoise.song().patterns[pattern_idx]  
  

even though the end result is the same thing. Had to do with something techy, maybe that the latter would reference the whole table of patterns, while the former only references the single pattern. Somehow. I dunno. But maybe this would be faster…? (UNTESTED…)

  
for order_idx = 1, #renoise.song().sequencer.pattern_sequence do  
 local pattern_idx = renoise.song().sequencer:pattern(order_idx)  
 for track_idx = 1, #renoise.song().tracks do  
 if renoise.song().sequencer:track_sequence_slot_is_selected(track_idx, order_idx) then  
 local track = renoise.song():pattern(pattern_idx):track(track_idx)  
 for row = 1, #track.lines do  
 local columns = track:line(row).note_columns  
 for column_idx = 1, #columns do  
 local column = track:line(row):note_column(column_idx)  
 if column.note_value <= 118 then  
 column.note_value = column.note_value + 1  
 end  
 end  
 end  
 end  
 end  
end  
  

Thanks! This is like 20x faster. Now I also finally understand these performance hints in Song.API.lua.
For random access the blah:something(index) is faster than the blah.somethings[index].
And for sequential access of all elements the pairs(blah.somethings) is even faster.
I changed your version to using pairs() and it’s like 50x faster.

  
for order_idx, order in pairs(renoise.song().sequencer.pattern_sequence) do   
 for track_idx, _ in pairs(renoise.song().tracks) do  
 if renoise.song().sequencer:track_sequence_slot_is_selected(track_idx, order_idx) then  
 local track = renoise.song():pattern(order):track(track_idx)  
 for _, line in pairs(track.lines) do  
 for _, note_column in pairs(line.note_columns) do  
 if note_column.note_value <= 118 then  
 note_column.note_value = note_column.note_value + 1  
 end  
 end   
 end  
 end  
 end  
end  
  

Brilliant! Are you gonna do a tool with it?

Do you mean a tool to have transpose short-cuts in the pattern matrix, like the short-cuts that exist in the pattern editor?

This is actually what I’m trying to get, but at first I need to learn how short-cut events are handled for Lua, and how to check the docking-pane focus or something to distinguish between pattern matrix and pattern editor.

Renoise 3.0 will probably have such short-cuts built-in or have a radio button “Selection in Matrix” in that operations tool on the right side, won’t it?