Then I will insist on using the XML format. I have already managed to successfully implement it to save XML banks in separate files. It will even allow you to check the mother folder to avoid errors.
I attach the code that I created for the creation of XML data banks. If someone sees any improvement, you just have to mention it. From what I’ve tried, it works perfectly.
Click to view contents
--
-- banks panel
--
class "Kng_Bank"
function Kng_Bank:__init( val )
self.cnt = vb:row { spacing = 3,
vb:text {
height = 21,
width = 21,
align = "right",
text = ("%.2d"):format( val )
},
vb:textfield {
id = "KNG_BANK_TXF_"..val,
height = 21,
width = 137,
text = ("Bank %.2d"):format( val ),
tooltip = ("Rename the bank %.2d"):format( val )
},
vb:row {
vb:row { spacing = -3,
vb:button {
id = "KNG_BANK_BT_LOCK_SAVE_"..val,
height = 21,
width = 25,
bitmap = "/ico/mini_padlock_close_ico.png",
notifier = function() kng_lock_save_bank( val ) end,
tooltip = ("Lock save the bank %.2d"):format( val )
},
vb:button {
active = false,
id = "KNG_BANK_BT_SAVE_"..val,
height = 21,
width = 35,
bitmap = "/ico/save_ico.png",
notifier = function() kng_save_bank( val ) end,
tooltip = ("Save the bank %.2d. Unlock before!"):format( val )
}
},
vb:button {
id = "KNG_BANK_BT_LOAD_"..val,
active = false,
height = 21,
width = 65,
text = ("Load %.2d"):format( val ),
notifier = function() kng_load_bank( val ) end,
midi_mapping = ("Tools:KangarooX120:Banks:Load %.2d"):format( val ),
tooltip = ("Load the bank %.2d"):format( val )
}
}
}
end
---
function kng_bank( val_1, val_2 )
local tbl = { 4,12,20,28,36,44,52,60,68,76,84,92 }
local bank = vb:column {}
for num = val_1, val_2 do
bank:add_child (
Kng_Bank( num ).cnt
)
if table.find( tbl, num, 1 ) ~= nil then
bank:add_child (
vb:space { height = 5 }
)
end
end
return bank
end
---
KNG_BANKS_1 = vb:row {
kng_bank( 1, 8 ),
vb:space { width = 6 },
kng_bank( 9, 16 ),
vb:space { width = 6 },
kng_bank( 17, 24 )
}
---
KNG_BANKS_2 = vb:row {
visible = false,
kng_bank( 25, 32 ),
vb:space { width = 6 },
kng_bank( 33, 40 ),
vb:space { width = 6 },
kng_bank( 41, 48 )
}
---
KNG_BANKS_3 = vb:row {
visible = false,
kng_bank( 49, 56 ),
vb:space { width = 6 },
kng_bank( 57, 64 ),
vb:space { width = 6 },
kng_bank( 65, 72 )
}
---
KNG_BANKS_4 = vb:row {
visible = false,
kng_bank( 73, 80 ),
vb:space { width = 6 },
kng_bank( 81, 88 ),
vb:space { width = 6 },
kng_bank( 89, 96 )
}
---
function kng_banks_sel( val )
if ( val == 1 ) then
KNG_BANKS_1.visible = true
KNG_BANKS_2.visible = false
KNG_BANKS_3.visible = false
KNG_BANKS_4.visible = false
vws.KNG_BANKS_SEL_1.color = KNG_CLR.WHITE
vws.KNG_BANKS_SEL_2.color = KNG_CLR.DEFAULT
vws.KNG_BANKS_SEL_3.color = KNG_CLR.DEFAULT
vws.KNG_BANKS_SEL_4.color = KNG_CLR.DEFAULT
elseif ( val == 2 ) then
KNG_BANKS_1.visible = false
KNG_BANKS_2.visible = true
KNG_BANKS_3.visible = false
KNG_BANKS_4.visible = false
vws.KNG_BANKS_SEL_1.color = KNG_CLR.DEFAULT
vws.KNG_BANKS_SEL_2.color = KNG_CLR.WHITE
vws.KNG_BANKS_SEL_3.color = KNG_CLR.DEFAULT
vws.KNG_BANKS_SEL_4.color = KNG_CLR.DEFAULT
elseif ( val == 3 ) then
KNG_BANKS_1.visible = false
KNG_BANKS_2.visible = false
KNG_BANKS_3.visible = true
KNG_BANKS_4.visible = false
vws.KNG_BANKS_SEL_1.color = KNG_CLR.DEFAULT
vws.KNG_BANKS_SEL_2.color = KNG_CLR.DEFAULT
vws.KNG_BANKS_SEL_3.color = KNG_CLR.WHITE
vws.KNG_BANKS_SEL_4.color = KNG_CLR.DEFAULT
else
KNG_BANKS_1.visible = false
KNG_BANKS_2.visible = false
KNG_BANKS_3.visible = false
KNG_BANKS_4.visible = true
vws.KNG_BANKS_SEL_1.color = KNG_CLR.DEFAULT
vws.KNG_BANKS_SEL_2.color = KNG_CLR.DEFAULT
vws.KNG_BANKS_SEL_3.color = KNG_CLR.DEFAULT
vws.KNG_BANKS_SEL_4.color = KNG_CLR.WHITE
end
end
---
KNG_BANKS_SEL = vb:column { spacing = -3,
vb:space { height = 5 },
vb:bitmap {
height = 27,
width = 56,
mode = "body_color",
bitmap = "/ico/bank_ico.png"
},
vb:text {
height = 19,
width = 56,
align = "center",
font = "big",
text = "Banks"
},
vb:space { height = 7 },
vb:button {
id = "KNG_BANKS_SEL_1",
height = 34,
width = 56,
color = KNG_CLR.WHITE,
text = "01 - 24",
notifier = function() kng_banks_sel( 1 ) end,
midi_mapping = "Tools:KangarooX120:Banks:Show Banks 01-24"
},
vb:button {
id = "KNG_BANKS_SEL_2",
height = 34,
width = 56,
text = "25 - 48",
notifier = function() kng_banks_sel( 2 ) end,
midi_mapping = "Tools:KangarooX120:Banks:Show Banks 25-48"
},
vb:button {
id = "KNG_BANKS_SEL_3",
height = 34,
width = 56,
text = "49 - 72",
notifier = function() kng_banks_sel( 3 ) end,
midi_mapping = "Tools:KangarooX120:Banks:Show Banks 49-72"
},
vb:button {
id = "KNG_BANKS_SEL_4",
height = 34,
width = 56,
text = "73 - 96",
notifier = function() kng_banks_sel( 4 ) end,
midi_mapping = "Tools:KangarooX120:Banks:Show Banks 73-96"
}
}
---
KNG_BANKS = vb:row { margin = 1,
visible = false,
vb:row { margin = 5, style = "panel",
vb:column {
KNG_BANKS_1,
KNG_BANKS_2,
KNG_BANKS_3,
KNG_BANKS_4
},
vb:space { width = 12 },
KNG_BANKS_SEL
}
}
--lock save bank
KNG_BANK_LOCK_SAVE = { --96
true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true
}
function kng_lock_save_bank( val )
if ( KNG_BANK_LOCK_SAVE[val] == true ) then
vws["KNG_BANK_BT_SAVE_"..val].active = true
vws["KNG_BANK_BT_LOCK_SAVE_"..val].bitmap = "/ico/mini_padlock_open_ico.png"
KNG_BANK_LOCK_SAVE[val] = false
else
vws["KNG_BANK_BT_SAVE_"..val].active = false
vws["KNG_BANK_BT_LOCK_SAVE_"..val].bitmap = "/ico/mini_padlock_close_ico.png"
KNG_BANK_LOCK_SAVE[val] = true
end
end
--save bank
function kng_save_bank( val )
--print (io.exists("banks"))
--check folder "banks", if it does not exist, create it
if ( io.exists("banks") == false ) then
--create new directory "banks"
os.mkdir("banks")
rna:show_status( "KangarooX120: The \"banks\" folder has been restored!" )
end
--create doc with pad data
local doc = renoise.Document.create("Kng_Bank_"..val.."") {
state = true,
nme = vws["KNG_BANK_TXF_"..val].text,
nte = KNG_PAD_NTE,
ins = KNG_PAD_INS,
trk = KNG_PAD_TRK,
vel = KNG_PAD_VEL,
clr = KNG_PAD_CLR.value
}
--save the doc in xml
doc:save_as("banks/bank_"..val..".xml")
kng_revise_bank( 1, 96 )
rna:show_status( ("KangarooX120: Bank %.2d saved! The 96 Banks have been revised again!"):format(val) )
--lock
vws["KNG_BANK_BT_SAVE_"..val].active = false
vws["KNG_BANK_BT_LOCK_SAVE_"..val].bitmap = "/ico/mini_padlock_close_ico.png"
KNG_BANK_LOCK_SAVE[val] = true
end
--load bank
function kng_load_bank( val )
--check folder "banks"
if ( io.exists("banks") == true ) then
--create neutral doc ( it is necessary for invoke after the doc:load_from() ), and not save!
local doc = renoise.Document.create("Kng_Bank_"..val.."") {
state = false,
nme = "",
nte = { 0 },
ins = { 0 },
trk = { 0 },
vel = { 0 },
clr = 1
}
--load doc to restore
doc:load_from("banks/bank_"..val..".xml")
--oprint(doc:property("state").value)
--import data to pad from xml
if ( doc:property("state").value == true ) then
for i = 1, 120 do
KNG_PAD_NTE[i] = doc:property("nte")[i].value
KNG_PAD_INS[i] = doc:property("ins")[i].value
KNG_PAD_TRK[i] = doc:property("trk")[i].value
KNG_PAD_VEL[i] = doc:property("vel")[i].value
vws["KNG_PAD_"..i - 1].text = ("%.2d\n%s %.2d\nTr%.2d"):format( i, kng_note_tostring( KNG_PAD_NTE[i] ), KNG_PAD_INS[i], KNG_PAD_TRK[i] )
vws["KNG_PAD_ROT_VEL_"..i - 1].value = KNG_PAD_VEL[i]
end
KNG_PAD_CLR.value = doc:property("clr").value
rna:show_status( ("KangarooX120: Bank %.2d loaded!"):format(val) )
else
rna:show_status( ("KangarooX120: Bank %.2d is empty. Please, save before a Bank!"):format(val) )
end
else
rna:show_status( "KangarooX120: The \"banks\" folder does not exist! Save a bank first!" )
end
end
--revise bank
KNG_REVISE_BANK_STATE = true
function kng_revise_bank( bank_1, bank_2 )
--check folder "banks"
if ( io.exists("banks") == true ) then
for i = bank_1, bank_2 do
--create neutral doc ( it is necessary for invoke after the doc:load_from() ), and not save!
local doc = renoise.Document.create("Kng_Bank_"..i.."") {
state = false,
nme = "",
nte = { 0 },
ins = { 0 },
trk = { 0 },
vel = { 0 },
clr = 1
}
--load doc to restore
doc:load_from("banks/bank_"..i..".xml")
--check state, and change "active" of load button and "name" of textfild
if ( doc:property("state").value == true ) then
vws["KNG_BANK_BT_LOAD_"..i].active = true
vws["KNG_BANK_TXF_"..i].text = doc:property("nme").value
else
vws["KNG_BANK_BT_LOAD_"..i].active = false
vws["KNG_BANK_TXF_"..i].text = ("Bank %.2d"):format( i )
end
end
if ( KNG_REVISE_BANK_STATE == false ) then
return
else
rna:show_status ("KangarooX120: 96 banks have been revised!" )
KNG_REVISE_BANK_STATE = false
end
else
rna:show_status( "KangarooX120: The \"banks\" folder does not exist! No banks!" )
end
end