Snippet: Convert Song From Lpb4 To Lpb12

Needed a higher resolution for one of my songs and instead of changing everything manually i’ve written a small script which does the work for me and which also stretches out the automation envelopes correctly. Might be useful for someone else too maybe. This script will take a while to process, so be sure to answer “no” if Renoise asks you to abort it. Only thing one needs to adjust afterwards are any effects which use LPC as timebase.

  
local rs = renoise.song()  
  
rs.transport.lpb = rs.transport.lpb * 3  
  
for _, pattern in ipairs(rs.patterns) do  
  
 local old_number_of_lines = pattern.number_of_lines  
  
 pattern.number_of_lines = pattern.number_of_lines * 3  
  
 for _, track in ipairs(pattern.tracks) do  
  
 for i = old_number_of_lines, 2, -1 do  
 if not track.lines[i].is_empty then  
 track.lines[i * 3 - 2]:copy_from(track.lines[i])  
 track.lines[i]:clear()  
 end  
 end  
  
 for _, automation in ipairs(track.automation) do  
 for _, point in ripairs(automation.points) do  
 if point.time == old_number_of_lines then  
 automation:add_point_at(point.time * 3, point.value)  
 automation:remove_point_at(point.time)  
 elseif point.time > 1 then  
 automation:add_point_at(point.time * 3 - 2, point.value)  
 automation:remove_point_at(point.time)  
 end  
 end  
 end  
  
 end  
  
end  

would be great if someone could make a tool out of this, where you can adjust ‘from LPB X to LPB Y’ variables. If it could auto adjust sample sync values in the instrument settings tab that be awesomest :) .

this might come in handy,i have a folder of tracks i want to change from lpd 8 to lpd 12,so i will try this out tonight,thanks for sharing

EDIT:i just quickly tried this on a track where i use lpd 8 and it didnt change the lpd to 12 but it changed it to lpd 24

i then tried it on another track just to check if i did a mistake and there it changed it from lpd 8 to lpd 12

+1 for a tool to change LPB on the whole track and automations…

Please! :slight_smile:

This is correct behaviour, it triples the original LPB value.

No idea how this happened, the snippet always triples the LPB as said above. It’s not flexible enough currently to support a LPB8 to LPB12 conversion.

Making a proper tool out of this snippet is quite a bit more complex, since one has to take care of fractional line numbers and offset stuff using the delay column. In this case it can also happen, that one has to move notes or effects to a new column so nothing get’s overwritten. LPB4 to LPB12 is quite simple, since it’s at least double the orginal value and one doesn’t need to deal with that stuff.

Also i have used a special conversion for the automation in my snippet, which makes sure if an automation has a point in the last line it always stays there after conversion. This might be unwanted behaviour in some cases but was useful for my song, which mainly uses automation to fade stuff.

There will be no tool from me for this in the near future, sorry, already have to many things scheduled. This was just a quick and dirty helper… would’ve taken ages if done manually. ;)

ahh yes i found out,but it works well for what i need to do,so thank you so much for sharing this

EDIT:i just tried this on a track that has sync on samples enabled,and even if the results was a bit weird sounding,it was actually really cool,so i will make a remix of that track

nice way to get inspiration :dribble:

But if you’ve written triplets in 4lpb the second is still going to be 2/3rd (AA, or D8) I assume you deal with this correctly as it would move it to a later line. Already does need thinking about with the simple tripling used to go from 4 to 12 LPB.

A tip for a more efficient version: Calling track.lines[x] within the loop is a lot slower than calling track:line(x), because track.lines will query all lines of the track, but then only access one of them:

[luabox]
local rs = renoise.song()

rs.transport.lpb = rs.transport.lpb * 3

for _, pattern in ipairs(rs.patterns) do
local old_number_of_lines = pattern.number_of_lines
pattern.number_of_lines = pattern.number_of_lines * 3

for _, track in ipairs(pattern.tracks) do
for line_index = old_number_of_lines, 2, -1 do
local src_line = track:line(line_index)

if (not src_line.is_empty) then
local dest_line = track:line(line_index * 3 - 2)
dest_line:copy_from(src_line)
src_line:clear()
end
end

for _, automation in ipairs(track.automation) do
for _, point in ripairs(automation.points) do
if (point.time == old_number_of_lines) then
automation:add_point_at(point.time * 3, point.value)
automation:remove_point_at(point.time)

elseif (point.time > 1) then
automation:add_point_at(point.time * 3 - 2, point.value)
automation:remove_point_at(point.time)
end
end
end

end

end
[/luabox]

i just tried taktiks "tip"and it sure is alott faster

Well, if one would make it perfect i’d converted any LFO automations, any delays with line sync on and so on too. It get’s the job done quickly with only minor things to adjust afterwards for a specific case. This small script took me maybe 20 minutes to program which included reading the docs. Only a short pause and i was able to further work on the song, not focussing on boring corrections for lot’s of patterns because i’ve changed the LPB value. I’m really thankful for having scripting support now, which makes such small but time consuming tasks so easy to solve. :)

That’s some massive speed improvement. Would’ve thought that the line implementation uses some sort of internal pointers to the correct line if it’s addressed with an index. Good tip in general to watch out for then.

Great snippet, I have a couple of songs in need. I changed the snippet into a tool for ease of access.

edit: Changed to taktiks improved code.

edit (16.11.2010): v 0.2 Added recalculation of beat synced instruments.

edit (19.03.2011): v 0.3 Improved error handling and updated for 2.7 beta (76 dl)

edit (23.04.2012): v 0.4 Version Notes:

  • Updated to API version 3 for Renoise 2.8
  • Added recalculation of delay column values for note columns.
  • Added handling of (some) effect column commands related to time. (ZL, ZD, ZQ, 0U, 0D, 0G, 0I, 0O, 0Q, 0C)
  • Added handling of (some) effect commands in volume (Ix, Ox, Qx, Cx) and panning (Jx, Kx, Qx, Cx) columns.

Thanks, will be useful.

Cool. Please have a look at the optimized version (Post #8 in this thread), which avoids calls to lines and uses :line() instead. This makes a huge difference performance wise…

thanks for making this into a tool mogue but please implement taktiks snippet code,it makes it sooo much faster

Done! I updated the xrnx file in the post above.

awesome works great,thanks for making this a tool,will come in handy for sure

Yeah!! Great tool! Thanks!!

Added recalculation of beat synced instruments. (see post above for a new XRNX file)

  
for _, instrument in ipairs(rs.instruments) do  
 for _, sample in ipairs(instrument.samples) do  
 if (sample.beat_sync_enabled == true) then  
 sample.beat_sync_lines = sample.beat_sync_lines * multiplier  
 end  
 end  
end  

Had a crash in Moque’s LPB tool:

C:\Users\plugexpert\AppData\Roaming\Renoise\V2.6.0\Scripts\Tools\mogue.beatslayer.LPBx.xrnx\main.lua' failed in one of its notifiers.  
  
Please contact the author (Beatslaughter) for assistance...  
  
std::logic_error: 'automation.point: invalid point time. time must be >= 1 and <= ARenoiseLuaPattern::kMaxNumberOfLines'  
stack traceback:  
 [C]: in function 'add_point_at'  
 main.lua:37: in function 'run'  
 main.lua:69: in function <69><br>```

</69>

[quote=“Jonas, post:19, topic:30227”]
Had a crash in Moque’s LPB tool:

C:\Users\plugexpert\AppData\Roaming\Renoise\V2.6.0\Scripts\Tools\mogue.beatslayer.LPBx.xrnx\main.lua' failed in one of its notifiers.  
  
Please contact the author (Beatslaughter) for assistance...  
  
std::logic_error: 'automation.point: invalid point time. time must be >= 1 and <= ARenoiseLuaPattern::kMaxNumberOfLines'  
stack traceback:  
 [C]: in function 'add_point_at'  
 main.lua:37: in function 'run'  
 main.lua:69: in function <69><br>```

<br>[/quote]<br>
<br>
This looks like you have automation data outside the pattern scope. So your pattern was longer you shortened it but didn't remove the excess data. You can solve this manually by lengthening your patterns and removing any extra automation or notes/effects before running LPBx.<br>
<br>
We could also strip out the out of scope notes and automation when using the tool. I'll check that out but you can fix this manually for now.</69>