Key-Bindings And Midi For Arranger Loop Extents

Something I would like to be able to do is change Loop Start and End points in the Arranger (I am NOT talking about sample loops here.)

This is to aid with using Renoise live. Say you have a four pattern loop as your main song structure, last pattern more hectic than the first three. You do your live fiddling, then want to move to loops just the last pattern four times before going into a two pattern breakdown.

So an option to increment/decrement the start and end points of the looped section in the pattern arranger would allow this to be done from either a keyboard combination or a MIDI controller. Maybe also a Set value option to allow it to be done from a knob or slider, rather than buttons. Obviously limited to 128 but should be enough for most situations.

If End is earlier than Start it turns off the Loop mode. Same value is obviously a single pattern looping.

Sounds like something that may be more of a task for scripting the for the Devs to hard code into the base software. So if it is already in the API I apologise, if not can it be added. If/Once it’s there would it be rude to ask this thread to be moved to the XRNX section? Although may be one for me to get my teeth into it myself, although been so busy lately not had a chance to even open 2.6 or look at the literature about scripting.

Anybody?

you want to hit a key that just loops the last pattern in the Matrix?
and you want to use a midi fader/knob to select start and stop of the selected area in the Matrix and a button to turn on looping right?

These options are doable, I can help you get started.

We are able to currently use OSC to turn on looping of a selected area in the pattern matrix, super easy too.
Translating that to MIDI shouldn’t be too much of a problem as we could use It Alien’s sample loop points experiment which uses MIDI, we can use that as a basis of functionality, and add a switch for keybinding and something for a midi button.

Mid-moving house at the moment so not had chance to fire up new Renoise and look fully at scripting, or get lost in the documentation of the API (although can find time for the forums at work in-depth reading while doing experiments isn’t really a possibility at the moment.)

Not tried looping from the pattern matrix, does that work? Thought you had to select in the Sequence Editor (just to left of Matrix) and then you can turn Looping on and from that selection. Slightly different way but if that is possible it would be a usable alternative. Set Loop to X amount of patterns, turn Loop On, change selection to next area, turn Loop Off and then On again and new highlighted section would then be set Loop once reached in the Sequence.

As I said for the moment just knowing that is definitely possible (IE in the API) before 2.6 goes Gold and I can’t request any additions is all I need right now. Once settled in my new place and have time to do things for myself I’d be willing to work on it and share, unless somebody else would find such functionality and wants to work on it (I can see it taking me some time with how my life is right now!)

Can every function in the API be binded to keyboard shortcuts and MIDI, if desired?

I’ve vaguely seen some changes recently made to the xrnx repository about key binding, that tells me it’s most probable.
With MIDI I would say it’s most certain, as any functions allowed in the API is also allowed to OSC, and while I haven’t touched any of the MIDI stuff, I have had the inclination to translate a couple simple MIDI functions to be usable with OSC.

Short answer: it’s possible.

I think it’s a great idea! To do it with a MIDI knob, add this code to the “GlobalMidiActions.lua” file :

[luabox]
add_action(“Loop Sequence:Loop Start [Set]”,
function(message)

local sequences = renoise.song().sequencer.pattern_sequence
local loop_end = renoise.song().transport.loop_sequence_end
local loop_start = renoise.song().transport.loop_sequence_start

if message:is_rel_value() then
local value = math.ceil(message.int_value / 64)
local new_start = math.min(math.max(loop_start + value, 0), #sequences)
local new_end = math.max(loop_end, new_start)
renoise.song().transport.loop_sequence_range = {new_start, new_end}
elseif message:is_abs_value() then
local value = math.ceil((message.int_value/128) * #sequences)
local new_start = math.min(value, #sequences)
local new_end = math.max(loop_end, new_start)
renoise.song().transport.loop_sequence_range = {new_start, new_end}
end

end)

add_action(“Loop Sequence:Loop End [Set]”,
function(message)

local sequences = renoise.song().sequencer.pattern_sequence
local loop_end = renoise.song().transport.loop_sequence_end
local loop_start = math.max(renoise.song().transport.loop_sequence_start, 1)

if message:is_rel_value() then
local value = math.ceil(message.int_value / 64)
local new_end = math.min(math.max(loop_end + value, 0), #sequences)
local new_start = math.min(loop_start, new_end)
renoise.song().transport.loop_sequence_range = {new_start, new_end}
elseif message:is_abs_value() then
local value = math.ceil(message.int_value / 128 * #sequences)
local new_end = value
local new_start = math.min(loop_start, new_end)
if new_start > new_end then new_end = 0 end
renoise.song().transport.loop_sequence_range = {new_start, new_end}
end

end)
[/luabox]

In my opinion it’s more convenient to set the start point with one knob (looping is disabled if 0), and to set the length of the loop with another. I guess it’s a matter of taste… Here’s how to do it like this :

[luabox]
add_action(“Loop Sequence:Loop Start (fixed loop length) [Set]”,
function(message)

local sequences = renoise.song().sequencer.pattern_sequence
local loop_end = renoise.song().transport.loop_sequence_end
local loop_start = renoise.song().transport.loop_sequence_start
local loop_length = loop_end - loop_start

if message:is_rel_value() then
local value = math.ceil(message.int_value / 64)
local new_start = math.min(math.max(loop_start + value, 0), #sequences)
local new_end = math.min(new_start + loop_length, #sequences)
renoise.song().transport.loop_sequence_range = {new_start, new_end}
elseif message:is_abs_value() then
local value = math.ceil((message.int_value/128) * #sequences)
local new_start = math.min(value, #sequences)
local new_end = math.min(new_start + loop_length, #sequences)
renoise.song().transport.loop_sequence_range = {new_start, new_end}
end

end)

add_action(“Loop Sequence:Loop Length [Set]”,
function(message)

local sequences = renoise.song().sequencer.pattern_sequence
local loop_end = renoise.song().transport.loop_sequence_end
local loop_start = renoise.song().transport.loop_sequence_start

if message:is_rel_value() then
local value = math.ceil(message.int_value / 64)
local new_start = loop_start
local new_end = math.min(math.max(loop_end + value, new_start), #sequences)
renoise.song().transport.loop_sequence_range = {new_start, new_end}
elseif message:is_abs_value() then
local value = math.ceil(message.int_value / 128 * #sequences)
local new_start = loop_start
local new_end = math.min(new_start + value, #sequences)
renoise.song().transport.loop_sequence_range = {new_start, new_end}
end

end)
[/luabox]

Thanks Bystrano.

Good to have the option of two ways of doing it. Can see benefits to both methods so guess it’s just a question of taste really :)