I have my MIDI controller set up in such a way that I use the actual computer keyboard as little as possible. One of the things that I seem to constantly come back to using the keyboard for is for the functionality of the arrow keys (left, down, right, up) to navigate in the pattern editor.
Since there is a lot of similar functionality already available in the MIDI mapping (such as next/previous column), would it also be possible to make it so that you can map keys on your midi controller to do these basic navigation functions?
Control of the cursor would be possible to support via the GlobalMidiActions (scripting).
Basically you would take a copy of the file - located in the preferences folder > Scripts (see Help > Show the Preferences folder), paste it into the Renoise application data folder (ā%appdata%/Renoise/V3.1.0/Scriptsā on my windows system) and then modify it to taste.
I could create these mappings for you, or you could give it a shot yourself?
If I were to create them, I would want it to be 1:1 with the actual keyboard navigation, meaning that going down one line will eventually make the cursor appear at the top of the pattern - unless the continuous movement option was enabled, in which case it would head into the first line of the next pattern.
One of the things that I seem to constantly come back to using the keyboard for is for the functionality of the arrow keys (left, down, right, up) to navigate in the pattern editor.
Since you want this āhands-offā type navigation, perhaps there are other things that you miss in particular?
Iād actually really like to learn a little bit of thisā¦ itās a teach a man to fish versus a catch him a fish sort of thing. Is there anything you can help me to get started? Like documentation about the file formats or any kind of scripting stuff I should learn. I see Lua mentioned a lot in conjunction with Renoise. Always wanted to learn thatā¦
Once you have enabled the scripting console you can evaluate code directly from there - makes it really easy to paste a few lines in and see if it works or breaks, and to consult the documentation for the whole Renoise API.
Also, this one about how to program with lua (difference from other languages):
OK, here are mappings for next/previous pattern-row that works exactly like the Renoise counterpart (including wrapped edit mode)
I also took time to add the ājump to quarter of patternā which are so useful on the QWERTY (F9-F12)
As for next/previous column - those mappings already exist, search for ācolumnā in the MIDI-mappings dialog
(they are as fine-grained as the Renoise API currently allows - no character-by-character navigation is possible yet)
Thanks a lot for your help. Is there some configuration file you created that I need to replace?
Yep, the file called GlobalMidiActions.lua. See my previous post where to find it.
First, find this file and open it in a text editor (the Renoise scripting console can be used for this purpose).
Then, to insert it a the right spot, search for a part with the text ā-- Navigationā (without quotes), and paste the code below before that text
Finally, save the document and hit the reload button in the MIDI mapping dialog
-- Navigation:Pattern Rows
add_action("Navigation:Columns:Jump To First Quarter Row [Trigger]",
function(message)
if message:is_trigger() then
song().selected_line_index = 1
end
end)
add_action("Navigation:Columns:Jump To Second Quarter Row [Trigger]",
function(message)
if message:is_trigger() then
song().selected_line_index = 1 + song().selected_pattern.number_of_lines/4*1
end
end)
add_action("Navigation:Columns:Jump To Third Quarter Row [Trigger]",
function(message)
if message:is_trigger() then
song().selected_line_index = 1 + song().selected_pattern.number_of_lines/4*2
end
end)
add_action("Navigation:Columns:Jump To Fourth Quarter Row [Trigger]",
function(message)
if message:is_trigger() then
song().selected_line_index = 1 + song().selected_pattern.number_of_lines/4*3
end
end)
add_action("Navigation:Columns:Move To Next Pattern Row [Trigger]",
function(message)
if message:is_trigger() then
local pattern = song().selected_pattern
local line_idx = song().selected_line_index
line_idx = math.min(pattern.number_of_lines,line_idx+1)
local wrapped_edit = song().transport.wrapped_pattern_edit
if (line_idx == song().selected_line_index) then
local seq_length = #song().sequencer.pattern_sequence
local new_seq_idx = song().selected_sequence_index
local new_line_idx = song().selected_line_index
local last_pattern_in_song = (song().selected_sequence_index == seq_length)
if last_pattern_in_song then
if not wrapped_edit then
new_line_idx = 1
end
else
new_seq_idx = wrapped_edit and new_seq_idx + 1 or new_seq_idx
song().selected_line_index = 1
end
song().selected_sequence_index = new_seq_idx
song().selected_line_index = new_line_idx
else
song().selected_line_index = line_idx
end
end
end)
add_action("Navigation:Columns:Move To Previous Pattern Row [Trigger]",
function(message)
if message:is_trigger() then
local line_idx = song().selected_line_index
line_idx = math.max(1,line_idx-1)
local wrapped_edit = song().transport.wrapped_pattern_edit
if (line_idx == song().selected_line_index) then
local first_pattern_in_song = (song().selected_sequence_index == 1)
local new_seq_idx = song().selected_sequence_index
local new_line_idx = song().selected_line_index
if first_pattern_in_song then
if not wrapped_edit then
local pattern_idx = song().sequencer.pattern_sequence[song().selected_sequence_index]
new_line_idx = song().patterns[pattern_idx].number_of_lines
end
else
new_seq_idx = wrapped_edit and new_seq_idx - 1 or new_seq_idx
local pattern_idx = song().sequencer.pattern_sequence[new_seq_idx]
new_line_idx = song().patterns[pattern_idx].number_of_lines
end
song().selected_sequence_index = new_seq_idx
song().selected_line_index = line_idx
else
song().selected_line_index = line_idx
end
end
end)
Sorry I havenāt been good at keeping up with this thread. Iām going to try this out now and Iāll let you know how it goes. Also thanks for doing this and giving me the code. This is a cool example to see how Renoise can be extended. Thanks for all your help.
EDIT
Maybe I misunderstood you. I see on Github where you have GlobalMidiActions.lua, however in my Preferences folder under scripts I donāt see an existing GlobalMidiActions.lua. I see what looks like things for Renoise plugins/extensions that I already installed. Am I supposed to just drop the modified file from Github in that Scripts directory, or is there somewhere else I should be looking for an existing file to modify?
EDIT 2
Sorry to spam the same postā¦ tried it out and it worked like a charm!!! Thank you so much!!!
I include related code for jump into patterns (works fine in R3.1):
function tool_02_CH01_5B()--JUMP NEXT PATTERN
local song = renoise.song()
local pos = song.transport.playback_pos
--print("pos.sequence:", pos.sequence)
pos.sequence = pos.sequence + 1
local seq_length = #song.sequencer.pattern_sequence
--print("number of patterns:", seq_length)
if (pos.sequence <= seq_length) then
song.transport.playback_pos = pos
end
end
function tool_02_CH01_6B()--JUMP PREVIOUS PATTERN
local song = renoise.song()
local pos = song.transport.playback_pos
--print("pos.sequence:", pos.sequence)
pos.sequence = pos.sequence - 1
if (pos.sequence >= 1) then
song.transport.playback_pos = pos
end
end
function tool_02_CH01_7B()--JUMP NEXT 4 PATTERNS
local song = renoise.song()
local pos = song.transport.playback_pos
--print("pos.sequence:", pos.sequence)
pos.sequence = pos.sequence + 4
local seq_length = #song.sequencer.pattern_sequence
--print("number of patterns:", seq_length)
if (pos.sequence <= seq_length) then
song.transport.playback_pos = pos
end
end
function tool_02_CH01_8B()--JUMP PREVIOUS 4 PATTERNS
local song = renoise.song()
local pos = song.transport.playback_pos
--print("pos.sequence:", pos.sequence)
pos.sequence = pos.sequence - 4
if (pos.sequence >= 1) then
song.transport.playback_pos = pos
end
end
Also includes condition āIfā with numbers to avoid mistakesā¦
Thanks for the code published in this post. It has served me for my tool.
just like our fellowgolfervrsboxer I was looking for a method to MIDI map a few functions and avoid moving my hands from my controller to my keyboard, back and forth.
Thanks to danoise I fixed half of my problem, but actually I need something more: Iād like to map the āINSā and āBACKā keys in order to insert and delete rows via MIDI.
Do you guys think it should be possible to implement?
Yes, actually I was thinking about inserting/deleting rows in a track!
Hopefully this is going to be the kickstart for someone to program the tool I need
I wish a lot more things were midi mappable. The disk browser, effects browser ā¦ a la Maschine, everything in the advanced pattern editor, etc. It would be cool to have an entire workflow through controllers.