Nice! but when I try and drag it onto renoise 2.81 here it will not install. The icon comes up as a recognized xrnx and I can launch renoise with it. It just won`t install.
Ahh I must of uploaded the version from before I fixed the error in the manifest.xml. Sorry for that, was late last night. I will get the correct version uploaded once I’ve had a shower ![]()
Here you go. Looks like I forgot to package it again after fixing the error in the local version. This one should work
/>/>
(Version with the selection loop included below.)
[quote=“kazakore, post:11, topic:37187”]
Here you go. Looks like I forgot to package it again after fixing the error in the local version. This one should work ![]()
Attachment 3761 not found.
Thanks, this is a nice proof of concept, I am having trouble with timing across patterns - I will investigate further. Looping a selection would certainly be a good step on! Will keep an eye out for any updates.
The thing that this hilights for me though is that more than just looping between two seperate patterns, the virtual pattern idea would be more improvement. i.e. [Line 32 of pattern 6 to line 32 of pattern 7] This way you could have all your shortcuts functional like nudging lines up/down for syncopating chords etc. To keep all these, this would need to be a native feature.
There is no “proof of concept” type programming in this. In fact it turned out to be the most simple tool I have ever programmed! Each function is only a single line. It uses the internal method of Renoise for setting start and end of loop, whether they be looped sequence or block loop within a pattern. Therefore it should be perfect and I’m surprised you’ve found problems with timing, although admit I was rushed for time and didn’t carefully check it so I might need a +1 or something to get it to use the correct like.
The snippet I posted a few lines before the tool does exactly that!
Not likely to be one to this tool but the shortcuts will appear in a future tool of mine or useful editing shortcuts…
Fair enough. Thought I’d knock it together when I realised how simple it actually was after creating the shortcuts to set start and end sequence for the loop sequence area.
Wasn`t a comment on your code, just the implementation of looping across patterns, maybe not the best technical use of terms.
It looked like you were planning to implement it.
Ok, will still keep an eye out.
cheers
Actually I’ve just tested it and although it uses what appear to be parameters from Renoise, rather than relying on notifiers and the GUI thread, it does stutter when going back patterns in the loop. That’s a shame.
Well as I have all the code…
3762 uk.deaddogdisko.TransitionLoop.V2.xrnx
I actually had to rewrite the Clear function to work with selection. For some reason the basic method I used previously didn’t want to work with it.
will take a look.
Cheers for sharing!
Could you check your posted Xrnx snippet?
You have one closing parenthesis too many.
'C:\Users\xxxxx\AppData\Roaming\Renoise\V2.8.1\Scripts\Tools\uk.deaddogdisko.TransitionLoop.xrnx\' failed to load.
Please remove this tool or contact the author (Kazakore | dj_kaza@hotmail.com) for assistance...
main.lua:41: unexpected symbol near ')'
Will try and find the time to have a look this evening if it’s quiet at work. Did check all function of the tool were working (at least from keyboard shortcuts) before packing and posting though…
I have only installed Renoise on the one computer at work I most often used. One of my colleagues is on it today. He was meant to finish at 6pm and is still here at well gone 9pm!!! Won’t he *%&£ing well go home?!?!?! ![]()
I think I might have some input to this discussion, as I have experienced this behaviour too
The stuttering is due to the way the loop is set - we basically have two methods:
renoise.song().transport.loop_range
-> [array of two renoise.SongPos objects]
and
renoise.song().transport.loop_range_beats
-> [array of two floats within 0 - song_end_beats]
The first one “sort of” adheres to the coeff (the 1/16, 1/5 and so on) being set in the Renoise UI, which can cause all manner of strange behavior.
But the second one seems to be precise enough to do exact line by line loops, regardless of the size.
Problem is, that you need to convert a position to the “beats” floating-point value, a bit tricky but consider the following code
(straight from the upcoming rewrite of the Duplex navigator app, feel free to use and abuse):
-- calculate the beat value from a renoise.SongPos object
function get_beats_by_songpos(pos)
local rns = renoise.song()
local seq_idx = pos.sequence
local line_idx = pos.line
assert(#rns.sequencer.pattern_sequence>=seq_idx,
"Oops, the sequence index is higher than the available number of patterns")
local total_lines = 0
for i = 1, seq_idx do
local patt_idx = rns.sequencer:pattern(i)
local num_lines = renoise.song().patterns[patt_idx].number_of_lines
if (i == seq_idx) then
if (num_lines < line_idx) then
print("The provided line does not exist, using the pattern length instead")
line_idx = num_lines
end
total_lines = total_lines + line_idx
else
total_lines = total_lines + num_lines
end
end
local beats = nil
if (rns.transport.timing_model == renoise.Transport.TIMING_MODEL_SPEED) then
local tpl = rns.transport.tpl
if (tpl == 1) then
beats = total_lines * (1/24)
elseif (tpl == 2) then
beats = total_lines * (1/12)
elseif (tpl == 3) then
beats = total_lines * (1/8)
else
beats = total_lines * (1/4)
end
else -- TIMING_MODEL_LPB
local lpb = rns.transport.lpb
beats = total_lines * (1/lpb)
end
return beats
end
-- test the code (change the values as you please)
local loop_start = renoise.song().transport.edit_pos
loop_start.sequence = 1
loop_start.line = 16
local loop_end = renoise.song().transport.edit_pos
loop_end.sequence = 2
loop_end.line = 15
local beat_start = get_beats_by_songpos(loop_start)
local beat_end = get_beats_by_songpos(loop_end)
print("beat_start",beat_start,"beat_end",beat_end)
renoise.song().transport.loop_range_beats = {beat_start,beat_end}
Can you explain why? Especially as when setting a Block Loop (as in the native Renoise function) it appears to set these settings? Or does it set both? (I haven’t looked at the other while making changes and my colleague is STILL here so can’t do so just yet…) It seems this should get to the core level of Renoise loops points and be flawless, but it isn’t, always stuttering the first line when looping back a pattern for some reason.
I was wondering for a minute why you’ve got a load of TPL stuff then I noticed you have the old and new method, to make it compatible with old songs. Something which I would never have thought to do! ![]()
Will have a look into the Beats method if it’s smoother, for my forthcoming Edit Shortcuts tool at least.
Can you explain why?
Well, I just experimented and observed. You can try it yourself, by replaceing loop_range_beats with loop_range
Comment out the last few lines where the beat-stuff is calculated, and insert a statement like this:
renoise.song().transport.loop_range = {loop_start,loop_end}
You’ll most likely see a lot of values get mixed up, not being set to the right value, or even shifting after the value has been set !!
I have no idea why, but the floating point value doesn’t seem to exhibit such a quirky behavior ![]()
Btw: I just noticed that the looped pattern sequence gets painted with a “weak” highlight when you use such values
Normally, the looped is entirely filled with gray but these look different. Very subtle, but noticeable
/>

It does that if only part of the pattern is looping but the loop spans more than one pattern (it does seem like it has been pretty much developed by the Devs just not quite implemented.)
You also get the highlighting of the line numbers, a la a Block Loop, with this method.
If you ask me, that’s the great thing about the API. You get these little surprises every now and then ![]()
I’m doing some work on my own script right now, it needs to handle three modes of looping
- The native block loop, restricted in size by the coefficient value and transferred from pattern to pattern as you navigate
- The native sequence loop, restricted by the pattern size and overruled by the block loop (as you can have a block loop inside a sequence loop)
- The “custom loop”, based on beat values. This one seem like the solution for transition loops, but will reset both the block and sequence loop once defined.
Edit: oh, and there’s the pattern loop as well. I’ve chosen to leave that one alone, as it’s good to have a simple type of loop that can simply be toggled on and off.
The beats one will get thrown off if there are any changes to LPB wont it? Although I guess that is quite a special case at the time time a transition is exactly the place you’re most likely to have a change…
Yeah, if it was dynamically linked to the playback engine. But I think this is simply a fire and forget, where you set the range you wish to loop - just using some different terms. In the end I’m guessing it gets translated into static song positions.
Scratch that, it is in fact linked to the tempo and will update in realtime. I tried to create loop spanning a couple of patterns and then changed the LPB to a lower value. The result was a range that “crawled” back towards the beginning of the song.
But what is worse is that the coefficient is still affecting the possible size of the looped range. I thought I had come up with a solution, but if you take my example, and enter some “strange” value that cannot be properly expressed by a coefficient, then the loop will be set, but “snap back” once the playback is toggled.
So, even though I’m not really a fan of introducing a fourth kind of loop into the Renoise UI (block loop, pattern loop, sequence loop, and now a transition loop?), coming up with a reasonably solid scripted solution seems to be very tricky. We need a surefire way of specifying a looped range, one that doesn’t get modified on the fly and doesn’t cause tempo glitches - adding this to the most wanted API features list.
Sorry it’s taken so long but finally fixed this and also added a +1 I had missed from the Loop Clear section. Something strange was also going on here and Loop Selection had also disappeared from the shortcuts list, even though it was working as I had tested it…
3789 uk.deaddogdisko.TransitionLoop.xrnx
Hopefully that solves any outstanding issues, beyond the fact you can’t do it completely perfect with the APi.
First off, I LOVE this plugin. I didn’t even realize I needed it until I was messing around and trying to make a song in 9/8. Block selection sorta falls apart in weird time signatures. But your plugin works great!
But there might be an issue where you can’t have the loop encompass the very last line of a pattern, because the loop actually ends one line before the selected end point instead of on the line of the selected end point. What do you think?
I changed this:
-- Set Loop Selection
local function loopsel()
local s = rns().transport.edit_pos
local e = rns().transport.edit_pos
s.line = rns().selection_in_pattern.start_line
e.line = rns().selection_in_pattern.end_line
rns().transport.loop_range = {s, e}
end
to
-- Set Loop Selection
local function loopsel()
local s = rns().transport.edit_pos
local e = rns().transport.edit_pos
s.line = rns().selection_in_pattern.start_line
e.line = rns().selection_in_pattern.end_line + 1
rns().transport.loop_range = {s, e}
end
Note the 3rd-to-last line.
Everything seems to work properly, including clearing a loop. Now when you make a selection, the loop includes the last line of the selection as well.
What do you think?
Edit:
Looks like I posted too soon. For it to work the way I described, you have to edit the setend() function as well:
-- Set Loop End
local function setend()
local e = rns().transport.edit_pos
e.line = rns().selection_in_pattern.end_line + 1
rns().transport.loop_range = {rns().transport.loop_range[1], e}
end
Attached is the version of the plugin that I am experimenting with. It may be unstable. I am still figuring out how to bundle plugins so bear with me.