is there a way to force LUA to open a XML?

let’s say i have a XML (device chain, in this case) - that i wish LUA to open with a shortcut, how would I go about integrating it into the LUA code?

I’m seeking a method where I either have a .xml file in the tool folder that is dynamically read and loaded into a device track chain, or a way to just paste the device chain data inside the main.lua and have it be brought up upon shortcut, midi-command or menu entry.

for details on (text) file i/o, consult http://www.lua.org/pil/21.1.html

the basics:

to read from or write into a file, we first have to set io.input to the desired filename.
we can use a relative or absolute path to do so, where the base folder being the folder where main.lua is located.

io.input(filename)  

now we can load the file into a variable.

local file_content = io.read("*all")  

afaik, it’s not possible to simply insert a device chain with a string. you have to insert devices one by one. individual devices can be manipulated using xml data by changing

renoise.song().tracks[].devices[].active_preset_data  

but in order to do so, if the device you want to manipulate doesn’t exist yet, you have to add a device using

renoise.song().tracks[]:insert_device_at(device_path, device_index)  

for detailed information on working with devices, consult the renoise.Track section of Renoise.Song.API

so in order to save and load device chains, you have to either save the devices individually, or save them all in one file and extracting the individual devices from it when needed. one way to do so is serialization. unfortunately, lua doesn’t provide it natively. read this: Table Serialization

EDIT: i forgot to talk about the “paste the device chain data inside the main.lua” part. if you really want just one specific or a few specific devices you want to include into your code directly, you can use multiline strings and string.format().

local my_multiline_string = [[this is a multiline string,  
 which can be formatted to dynamically  
 add values, like this integer: %i  
 or this string: %s]]  
  
local my_number = 3  
local my_string = "hi, i'm a string!"  
  
my_multiline_string = string.format(my_multiline_string,  
 my_number, my_string)  
  
print (my_multiline_string)  

more detailed information on string formatting: http://www.lua.org/pil/20.html

this whole thing makes me wonder if there’s actually a way to insert the Formula Device without wrecking the TrackDSP Chain…
(it resets it to only having the Formula Device)…

Yes you can do that, this code will insert a formula device to the right of the currently selected device:

local track = renoise.song().selected_track_index  
local device = renoise.song().selected_device_index + 1  
renoise.song().tracks[track]:insert_device_at("Audio/Effects/Native/*Formula", device)  

If you then want to populate this with some preset data you can use some of fraktals code examples to do this, so for example if I wanted to load the inertial slider I would first paste the device into Renoise and then read the xml data from the device using the lua terminal, like this:

print(renoise.song().tracks[track].devices[device].active_preset_data)  

This will output the xml data for the preset, for the inertial slider it looks like this:

  
<?xml version="1.0" encoding="UTF-8"?>  
<filterdevicepreset doc_version="9"><br>
  <deviceslot type="FormulaMetaDevice"><br>
    <ismaximized>true</ismaximized><br>
    <formulaparagraphs><br>
      <formulaparagraph>OUTPUT - (OUTPUT - A) * power_inertia(B, 0.025, 0.5)</formulaparagraph><br>
    </formulaparagraphs><br>
    <functionsparagraphs><br>
      <functionsparagraph>function power_inertia(inertia, min, max)</functionsparagraph><br>
      <functionsparagraph> inertia = 1.0 - inertia</functionsparagraph><br>
      <functionsparagraph> inertia = inertia * inertia * inertia</functionsparagraph><br>
      <functionsparagraph> return min + inertia * (max - min)</functionsparagraph><br>
      <functionsparagraph>end</functionsparagraph><br>
      <functionsparagraph></functionsparagraph><br>
    </functionsparagraphs><br>
    <inputnamea>Input</inputnamea><br>
    <inputnameb>Inertia</inputnameb><br>
    <inputnamec>_</inputnamec><br>
    <editorvisible>false</editorvisible><br>
    <panelvisible>0</panelvisible><br>
    <inputa><br>
      <value>0.0</value><br>
    </inputa><br>
    <inputb><br>
      <value>0.599999905</value><br>
    </inputb><br>
    <inputc><br>
      <value>0.0</value><br>
    </inputc><br>
  </deviceslot><br>
</filterdevicepreset>  
  

Copy this into a new text file and save it into the same folder as the tool (lets say as formula.xml) , you can then read from this when you want to load the preset after the device has been created, like this:

  
local infile = io.open( "formula.xml", "rb" )  
local indata = infile:read( "*all" )  
renoise.song().tracks[track].devices[device].active_preset_data = indata  
infile:close()  
  

The xml data doesn’t store the device control settings so you will then need to set these separately using ```
renoise.song().tracks[track].devices[device].parameters[].value

Dude! there’s a option for that in preferences… by Files section if I’m not mistaken… “Replace existing chain” can be ‘unchecked’.

Also if you still really wanna know about inserting just one device from lua code… check out my tool called SirDance-A-Lot (tool is for inserting devices with keyboard only, aka no mouse searching clicking and dragging to the right spot) - download link - tools page
Maybe you are very ok with the way the FX list is organised in Renoise, but I dislike the going there with mouse, scrolling, etc, and there is no nice way to control it with keyboard and insert it at a specific spot in the chain directly.
So I made this tool and in my example I’ve got it bound to Shift-F, and the ‘native only’ option to Shift-Control-F (Some deprecated devices are in the list too). So the set of keyboard commands: Shift-Control-F, F, O, Enter inserts a *Formula directly after the currently selected device.
One other thing the tool does, is when you insert a send it always sets the amount to -INF and the option to Keep Source.
The idea (getting offtopic already?) is combining this with a tool where you can just “fork”/split/parallel process a device chain with #Send.

Thanks, I just did that…

Added this too :) I had no idea the *Formula could be loaded, I do not see it in the list I can populate of trackdevices… I wonder what else there is that’s completely hidden

That’s super-ultra-lush… I gotta save this snippet for the future, because this would surely work better than the way I’ve done it previously, which would be stuff like

  
renoise.song().selected_track:insert_device_at("Audio/Effects/AU/aufx:KTGr:KTfx", 2)  
renoise.song().selected_track.devices[2].is_maximized=true  
renoise.song().selected_track.devices[2].parameters[31].value=1 --SplitPitch  
renoise.song().selected_track.devices[2].parameters[16].value=0.75 --maxTransp  
renoise.song().selected_track.devices[2].parameters[2].value=0.50 --Mix  
renoise.song().selected_track.devices[2].parameters[3].value=0.35 --Mix  
renoise.song().selected_track.devices[2].parameters[6].value=0.75 --Mix  
renoise.song().selected_device_index= 2   
  

Yes, I too dislike the mouse method, and adding keyboard shortcuts to my choice of VST/AU/Native FX was one of the first things i did, nice to see that others also think the same way… I too really enjoyed being able to set #Send to a specific way and have it work straight up without any clicking - it just improves the workflow immensely. I set FabFilter Pro-Q to always default to showing the sound spectrum, and that kind of stuff.

One neat thing I was working on, was a sample-looper recorder which would first create a #Line In, then remove it after the sample has been recorded by the sample recorder… so I could always monitor through efx on the channel i am on, no matter which channel Im in… it’s just gr8 to be able to have stuff like this.

p.s. the way I have stuff set up for bringing native/vst/au efx is like this:
Shift-O = Ohmboyz, Shift-F = Fusion Field, Shift-E = Schaack Transient Shaper, Shift-A =D16 Syntorus, Shift-K =Kt_Granulator, Shift-W = W1, Shift-Z = FabFilter Pro-Q, Shift-V =ValhallaRoom, shift-C = ValhallaShimmer, Shift-B = ValhallaFreqEcho, Shift-P = Predatohm, Shift-H = Hematohm…

That kinda stuff :)

i hope, i understand you correctly, but i tried this and it worked:

local dest_min = 0.2  
local dest_max = 0.8  
  
renoise.song().selected_track:insert_device_at("Audio/Effects/Native/*Key Tracker", 2)  
  
renoise.song().selected_track.devices[2].active_preset_data = string.format(([[<?xml version="1.0" encoding="UTF-8"?>  
<filterdevicepreset doc_version="9"><br>
  <deviceslot type="KeyTrackingDevice"><br>
    <ismaximized>true</ismaximized><br>
    <srcinstrument>-1</srcinstrument><br>
    <destscaling>Linear</destscaling><br>
    <keytrackingmode>Clamp</keytrackingmode><br>
    <keytrackingmin>36</keytrackingmin><br>
    <keytrackingmax>72</keytrackingmax><br>
    <destmin><br>
      <value>%g</value><br>
    </destmin><br>
    <destmax><br>
      <value>%g</value><br>
    </destmax><br>
  </deviceslot><br>
</filterdevicepreset>]]), dest_min, dest_max)  

so you can, in fact, use xml data to directly set device parameters.

ahh, this was the exact thing i was looking for! just to dump the xml in… thanks folks!

Sorry, what I meant was the parameters for destination track, device and parameter that are to be controlled by the meta device, as far as I can tell, these aren’t stored in the xml data. So if you want to set up a keytracker controlling a hydra you need to use a combination of loading the xml preset and setting the destination parameters separately.

BTW… I had been trying to figure out how to contain the xml data in script rather than in a separate file so thanks for the code snippet

Haha, I did think that… I expect it will be deprecated devices… Although I hope there will be some uber experimental v3 devices hidden away somewhere, maybe a lolcat device

oh, right, got ya!

actually, that’s what i tried to tell you with my example in my first post. instead of xml data, i used some random multiline string, but it’s the same principle. :lol:

well, the “my_string” kinda confused me because it seemed to be that it was regular text string, not just

That’s nice, although I don’t use any of those tho…
Anyway what I want you to understand is the subtle difference, while of course your method is probably quickest if you use mostly those 10 FX… this is a screenshot of the tool I’m talking about (from the tools page)

so it gets the possible FX, and you can type-to-search and find any fx (vst/au/native, doesn’t matter) in a few keypresses. Try it! ;)