How To Call 3 Constants From Renoise.Applicationwindow?

Can I call a function which opens up these specific “views”?
renoise.ApplicationWindow.UPPER_FRAME_MASTER_SPECTRUM
renoise.ApplicationWindow.MIDDLE_FRAME_SAMPLE_EDITOR
renoise.ApplicationWindow.LOWER_FRAME_TRACK_DSPS

How would I go about doing it. I have an okay grasp on putting in a KeyBinding, if these… Constants, can somehow be called by a function?

  
renoise.app().window.active_upper_frame = renoise.ApplicationWindow.UPPER_FRAME_MASTER_SPECTRUM  
renoise.app().window.active_middle_frame = renoise.ApplicationWindow.MIDDLE_FRAME_SAMPLE_EDITOR  
renoise.app().window.active_lower_frame = renoise.ApplicationWindow.LOWER_FRAME_TRACK_DSPS  
  

Tip: The objinfo() function is really handy. You can use it to learn about the structure of things, what properties and methods are available, etc.

For example:

print( objinfo( renoise.song() ) )  
print( objinfo( renoise.app() ) )  
print( objinfo( renoise.app().window ) )  
  

Etc.

1 Like

I tried to print( objinfo( renoise.app().window.active_lower_frame ) ) and got a response of 0.

However, when I did the 3rd objinfo you suggested, I got these:

  
>>> print( objinfo( renoise.app().window ) )  
class: ApplicationWindow  
 properties:  
 active_lower_frame  
 active_lower_frame_observable  
 active_middle_frame  
 active_middle_frame_observable  
 active_upper_frame  
 active_upper_frame_observable  
 fullscreen  
 is_maximized  
 is_minimized  
 lock_keyboard_focus  
 lower_frame_is_visible  
 lower_frame_is_visible_observable  
 mixer_view_post_fx  
 mixer_view_post_fx_observable  
 pattern_advanced_edit_is_visible  
 pattern_advanced_edit_is_visible_observable  
 pattern_matrix_is_visible  
 pattern_matrix_is_visible_observable  
 sample_record_dialog_is_visible  
 upper_frame_is_visible  
 upper_frame_is_visible_observable  
 methods:  
 __STRICT  
 maximize  
 minimize  
 restore  
 select_preset  
  

Now, not knowing how to find out the possible settings for properties, how do I find the possible switches of properties - and how do methods mix into this?

… I was able to get

  
>>> print( objinfo( renoise.app().window.select_preset ) )  
function: 0x1b15b420  
>>> print( objinfo( renoise.app().window.sample_record_dialog_is_visible ) )  
false  
>>> print( objinfo( renoise.app().window.active_lower_frame ) )  
0  
>>> print( objinfo( renoise.app().window.active_lower_frame_observable ) )  
class: Observable  
 methods:  
 __STRICT  
 add_notifier  
 has_notifier  
 remove_notifier  

And it seems to me that defining that sample_record_dialog_is_visible = true should then make it possible to create a second keybind which both opens the sample record dialog and something else too…But that’s moving aside from the concept of opening f.ex. DiskOp/SampleEditor/InstrumentSettings (top,mid,lower) with one keybind shortcut. I see all of the 3 frames have a observable in addition…??

I use a a variation of this function to “dbug”

  
-- Debug print  
function dbug(msg)  
 local base_types = {  
 ["nil"]=true, ["boolean"]=true, ["number"]=true,  
 ["string"]=true, ["thread"]=true, ["table"]=true  
 }  
 if not base_types[type(msg)] then oprint(msg)  
 elseif type(msg) == 'table' then rprint(msg)  
 else print(msg) end  
end  
  

Then when you do dbug(foo), no matter what foo is, something useful will print.

1 Like

First of all, I would definitely recommend looking through the scripting documentation, which you can find in your Renoise installation folder under \Scripts\Documentation\ . This should clear up quite a few things for you, and in particular I would suggest Renoise.Application.API.lua for more info relating to the window handling stuff. (I guess you’ve read it already if you knew about the constants, but it’s worth going over again just in case)

If the lower frame is hidden then it will return 0 (although you should use lower_frame_is_visible instead for this purpose), otherwise it will return the index of the currently visible tab from 1 to 4. These values also correspond to the constants that are defined, being numbered from 1 to 4 respectively:

  
renoise.ApplicationWindow.LOWER_FRAME_TRACK_DSPS  
renoise.ApplicationWindow.LOWER_FRAME_TRACK_AUTOMATION  
renoise.ApplicationWindow.LOWER_FRAME_INSTRUMENT_PROPERTIES  
renoise.ApplicationWindow.LOWER_FRAME_SONG_PROPERTIES  
  

The observable function lets you keep track of when a change occurs, so that your tool can react to this if it needs to.

For example:

  
-- create a reference that we can easily re-use  
local window = renoise.app().window  
  
-- notifier function  
function upper_frame_changed()  
 print('Upper frame changed to: ' .. window.active_upper_frame)  
end  
  
-- add notifier  
if (not window.active_upper_frame_observable:has_notifier(upper_frame_changed)) then  
 window.active_upper_frame_observable:add_notifier(upper_frame_changed)  
end  
  
-- change upper frame  
window.active_upper_frame = renoise.ApplicationWindow.UPPER_FRAME_DISK_BROWSER  
window.active_upper_frame = renoise.ApplicationWindow.UPPER_FRAME_TRACK_SCOPES  
window.active_upper_frame = renoise.ApplicationWindow.UPPER_FRAME_MASTER_SCOPES  
window.active_upper_frame = renoise.ApplicationWindow.UPPER_FRAME_MASTER_SPECTRUM  
  
-- remove notifier when we're done with it  
if (window.active_upper_frame_observable:has_notifier(upper_frame_changed)) then  
 window.active_upper_frame_observable:remove_notifier(upper_frame_changed)  
end  
  

Excellent tip!

A constant cannot be changed. It just means “hardcoded” variable.

So, internally, renoise might represent renoise.ApplicationWindow.MIDDLE_FRAME_SAMPLE_EDITOR as 4. Might even change depending if you are on different cpu architecture. Whatever, it’s none of your concern.

To change the upper frame to Master Spectrum:

  
renoise.app().window.active_upper_frame = renoise.ApplicationWindow.UPPER_FRAME_MASTER_SPECTRUM  
  

Most of the time in the code you will see in the wild, this will be reduced to something like:

  
local window = renoise.app().window  
local app_window = renoise.ApplicationWindow  
--  
-- Some stuff happens  
--  
window.active_upper_frame = app_window.UPPER_FRAME_MASTER_SPECTRUM  
  

Because if you are doing hundreds of lines of code you don’t want to type things over and over…

EDIT: And dblue beat me to the punch with better info.

Hope this helps.

1 Like

Thanks, I also got some help from joule on esper.net #renoise:

  
renoise.app().window.sample_record_dialog_is_visible = true ![:)](https://files.renoise.com/forum/emoticons/default/smile.gif)  
renoise.app().window.active_middle_frame = 4 brings forward the sample view  
Renoise.Application.API.lua from row 148  
you will have to use renoise.app().window.active_middle_frame = number, renoise.app().window.active_upper_frame = number, renoise.app().window.active_lower_frame = number  
  

After some mucking around with everything that all three of you said, I ended up using dBlue’s print objinfo to figure out this:

  
  
function showsomething()  
renoise.app().window.lower_frame_is_visible = true  
renoise.app().window.upper_frame_is_visible =true  
renoise.app().window.active_upper_frame = 2  
renoise.app().window.sample_record_dialog_is_visible = true   
renoise.app().window.active_middle_frame = 4  
renoise.app().window.active_lower_frame = 4  
renoise.song().transport:panic()  
end  
  
renoise.tool():add_keybinding {  
 name = "Global:Transport:Show Something",  
 invoke = function() showsomething()  
 end  
 }  
  

Thus this being my first Scriptual replacement for Global View Presets (since suggesting to people to copy paste a Config.XML GUI Global View Presets text from a website - and going to their Preferences and loading config.xml in - and pasting these global view presets into their config.xml - is simply far too cumbersome, when trying to offer people ImpulseTracker -like screensettings that are both IT-usable and taking advantage of the new features of Renoise.)))

My next question would be, how can I use a script to auto-open the “Phase Meter” or Disk Browser at “More” mode?

This is a great tip. My question is, does the Renoise LUA Script editor allow for some form of aliases, something like this:

  
alias objinfo="print (objinfo( $1 ) )"  
  

where objinfo $1 would result in the output? :)

I don’t believe it’s possible to create your own aliases, but in this particular instance you can just use the oprint() function instead which does the same thing as print(objinfo())

I just used both functions in my example to show that information could be retrieved via objinfo() and then used by your own scripts for some interesting purpose.

Conner’s snippet mentioned above is incredibly useful as well if you want something easy that can handle all data/object types, but you will of course need to use this within the context of a .lua script, rather than simply calling it from the terminal.

I think Conner’s small snippet reaches as close to the idea as you want to get and beyond.

I’m not entirely certain how to make sure it is implemented everytime Renoise is started. How do I go about doing that?

You could make a file called “debug_classes.lua” and simply add
require “debug_classes.lua” in each project.
Then you can call all these functions everytime you quickly need them.

do take care that you remove it when you are publishing your tool to the outside world.

So it has to be present in the folder itself, and I cannot just use TestPad.lua?

If you want to add it to testpad.lua, it should be possible.
I never worked with testpad.lua, so can’t tell you exactly about that.

Try as I might I can’t seem to poke& prod renoise.tool().preferences . I’m hoping that inside it is some .list_folder or something which , when properly used, would let me define a button (can do that) which opens up a filepath (can do that) - the filepath being the default preferences folder.
What am I doing wrong?
Is renoise.tool().preferences just something I can’t objinfo, rprint, oprint or dbug? :)

I wonder what I’m doing wrong?

  
>>> print( objinfo( renoise.tool() ))  
*** [string "print( objinfo( renoise.tool() ))"]:1: attempt to call field 'tool' (a nil value)  
*** stack traceback:  
*** [string "print( objinfo( renoise.tool() ))"]:1: in main chunk  
  

If you try to access renoise.tool() from the scripting terminal, then there is no tool loaded in memory at that point, so what do you expect it to do? :)

However, if you access renoise.tool() within the context of your actual tool (from a function in your main.lua or something similar), then you will actually get back some useful data.

It’s all about context really :)

So basically, according to this, there’s no way to extract the Preferences location folder for Renoise? :)

Sorry, I accidentally missed your earlier post.

renoise.tool().preferences does not actually refer to Renoise’s own preferences. This property lets you assign a custom document to your tool which you can use to save any settings your tool might need to remember each time it runs.

For example: (this would go in your main.lua before your main functionality)

  
-- Create a custom document to store some crap in  
my_prefs = renoise.Document.create("ScriptingToolPreferences") {  
 some_bool = true,  
 some_string = "foo",  
 some_number = 123  
}  
  
-- Assign custom document to tool preferences  
renoise.tool().preferences = my_prefs  
  

And then later in some function of your tool…

  
-- Read values   
local my_bool = my_prefs.some_bool.value  
local my_string = my_prefs.some_string.value  
local my_number = my_prefs.some_number.value  
  
-- Write values   
my_prefs.some_bool.value = false  
my_prefs.some_string.value = "bar"  
my_prefs.some_number.value = 321  
  

If you wanted to get at Renoise’s own preferences (stored in Config.xml) then it should still be possible to at least read from it, but you won’t be able to write anything and you’ll have to manually find your way to the file itself with a little bit of hacking :)

  
function get_config_folder()  
 local os = os.platform()  
 local log_filename = renoise.app().log_filename  
 local config_folder = ''  
 if (os == 'WINDOWS') then  
 config_folder = string.gsub(log_filename, '\\Log.txt', '\\')  
 elseif (os == 'MACINTOSH') then  
 config_folder = string.gsub(log_filename, '/Logs/Renoise.log', '/Preferences/Renoise/V' .. renoise.RENOISE_VERSION .. '/')  
 elseif (os == 'LINUX') then  
 config_folder = string.gsub(log_filename, '/Log.txt', '/')  
 end  
 return config_folder  
end  
  
function get_config_filename()  
 return get_config_folder() .. 'Config.xml'  
end  
  

Edit: Updated get_config_folder() and get_config_filename() functions above. Many thanks to esaruoho for working with me to find the correct values necessary for Mac and Linux!

Ok, here’s my question. I’ve tried dbug, objinfo etc on this stuff:
renoise.song().instruments[].samples[].loop_mode

I’ve tried to set it to 1 2 and 3 and 0, but everytime I type renoise.song().instruments[].samples[].loop_mode=1 in the terminal, nothing happens.
I’ve tried putting instrumentnumbers and samplenumbers of the instruments into it, but I still can’t seem to figure out how to access these. How come I can’t poke this to find out the controls? :)

renoise.Sample.LOOP_MODE_FORWARD

(edit)
Okay… :)
renoise.song().selected_sample.loop_mode=0 to 3 will do