Which is all the data from that particular track that I want, however the ‘line’ variable is only pointing to that particular line so if I clear the track then I lose the data in ‘line’. I can get around this by doing
line = tostring( renoise.song().patterns[1].tracks[1]:line(1) )
Which works, so I then have the data stored in a string, but now I cannot find a quick way to write this data back to the track at a later stage. The only way I can think of is to iterate over each note and effect column and write the data back from the string variable I have stored it in, this seems a slow way do it.
Another way I can think of is to copy the track into a temporary pattern and then use
*** [string “-- create or convert a table to an object t…”]:93: bad argument #1 to ‘table.copy’ (table expected, got ‘PatternTrackLine’)
*** stack traceback:
*** [C]: in function ‘assert’
*** [string “-- create or convert a table to an object t…”]:93: in function ‘copy’
*** testlib.lua:66: in main chunk
OK, seems it is a PatternTrackLine object, not a table as such. Sure with these types of Renoise defined objects using var = object actually copies the object, not just points to it like it does with a table. If you use var = renoise.song().patterns[1].tracks[1]:line(1) and then edit line 1 and after print var does it really print the changed value?
(Sorry can’t be done in the TestPad and not got the time to try and set up a quick test tool right now… Especially with how much my GUI skills suck!!)
Yep it prints the changed value, if I run this code:
line = renoise.song().patterns[1].tracks[1]:line(1)
renoise.song().patterns[1].tracks[1]:clear()
print (line)
I get an output of a blank pattern line, doing these steps in the terminal gives the same results, the variable always points to what is currently in the line so it seems it only references.
--------------------------------------------------------------------------------
-- copy all effect column properties from src to dest column
local effect_column_properties = {
"number_value",
"amount_value",
}
function copy_effect_column(src_column, dest_column)
for _,property in pairs(effect_column_properties) do
dest_column[property] = src_column[property]
end
end
--------------------------------------------------------------------------------
-- copy all note column properties from src to dest column
local note_column_properties = {
"note_value",
"instrument_value",
"volume_value",
"panning_value",
"delay_value",
}
function copy_note_column(src_column, dest_column)
for _,property in pairs(note_column_properties) do
dest_column[property] = src_column[property]
end
end
--------------------------------------------------------------------------------
-- creates a copy of the given patternline
function copy_line(src_line, dest_line)
for index,src_column in pairs(src_line.note_columns) do
if (not dest_line.note_columns[index]) then
dest_line.note_columns[index] = {}
end
local dest_column = dest_line.note_columns[index]
copy_note_column(src_column, dest_column)
end
for index,src_column in pairs(src_line.effect_columns) do
if (not dest_line.effect_columns[index]) then
dest_line.effect_columns[index] = {}
end
local dest_column = dest_line.effect_columns[index]
copy_effect_column(src_column, dest_column)
end
end
--------------------------------------------------------------------------------
--- test
local src_line = renoise.song().selected_line
local temp_line = { note_columns = {}, effect_columns = {} }
copy_line(src_line, temp_line) -- create copy
src_line:clear() -- modify line
copy_line(temp_line, src_line) -- restore line from copy
That’s very useful, although completely different to the approach I have taken!
I have come up with this:
-- Function to copy track line data
local function copy_line(pattern, track, line)
return tostring ( renoise.song().patterns[pattern].tracks[track]:line(line) )
end
-- Function to write track line data
local function write_line(source, pattern, track, line)
-- Write note values
for n = 0, 11 do
local s = n*14+1
local note = renoise.song().patterns[pattern].tracks[track].lines[line].note_columns[n+1]
note.note_string = string.sub(source, s, s+2)
note.instrument_string = string.sub(source, s+3, s+4)
note.volume_string = string.sub(source, s+5, s+6)
note.panning_string = string.sub(source, s+7, s+8)
note.delay_string = string.sub(source, s+9, s+10)
end
-- Write effect values
for n = 0, 7 do
local s = n*7+169
local efx = renoise.song().patterns[pattern].tracks[track].lines[line].effect_columns[n+1]
efx.number_string = string.sub(source, s, s+1)
efx.amount_string = string.sub(source, s+2, s+3)
end
end
-- Call it
write_line(copy_line(1,1,1), 1, 1, 33)
I want this to happen in realtime so I wonder which approach executes faster?
I took the following approach in the Clip Composing Language, which is similar to taktiks.
I would guess, my method is slightly faster than taktiks, as I don’t use string-indices for
the lua tables. But I can imagine, as you are using fixed string offsets, that your string
method is maybe even faster. But you can’t be sure without benchmarking yourself
class "CclLine"
function CclLine:__init (trackidx)
self.track = trackidx
self.nc = { } -- note columns
self.xc = { } -- fx columns
self.atm = { } -- automation data
end
function CclLine:from_line (line)
for i, c in ipairs (line.note_columns) do
if (not c.is_empty) then
self.nc[i] = {
c.note_value, c.instrument_value, c.volume_value,
c.panning_value, c.delay_value
}
end
end
for i, c in ipairs (line.effect_columns) do
if ((not c.is_empty) and c.number_string:sub (1, 1) ~= "Y") then
self.xc[i] = { c.number_value, c.amount_value }
end
end
end
function CclLine:write (line_idx, pattern, pattern_line)
pattern_line:clear ()
for i, v in pairs (self.nc) do
local nc = pattern_line:note_column(i)
nc.note_value = v[1]
nc.instrument_value = v[2]
nc.volume_value = v[3]
nc.panning_value = v[4]
nc.delay_value = v[5]
end
for i, v in pairs (self.xc) do
local xc = pattern_line:effect_column(i)
xc.number_value = v[1]
xc.amount_value = v[2]
end
-- snip --
end