[Fixed 2.8] Api Realtime Rendering Fails When Called From A Gui

Have you tried adding some kind of timer observable calling out to your render procedure?
It might be that the “unpress” button response for the GUI update somehow is interfering some process
By adding some timer observable to call the specific function after 10ms, it might solve your issue for now.

im not sure what a timer observable call is :)

Sorry, but I’m lost. Would be great if you could set up a small example song which fails to render along with a small snippet on how you do render? Does this snippet always render fine with Renoises render dialog or render selection commands. Aka, is this a script problem after all?

I seem to be unable to make a button start rendering, without the clicking-action on the button (click + release , on / off states of the button one after the other) affecting the functionality of line-in device in the case where i am to use your bit of code to render out a wavefile.

the same bit of code, when used as a keyboard shortcut, functions perfectly. for instance, i just pressed the shortcut, and had microphone input armed in line-in-device, made some clicky noises and they were recorded through renoise’s efx straight to a wav in a specific place, by a specific name.

Wow, what a crap. This indeed does not work when called from a dialog.

You can use this snippet as a workaround, until we’ve fixed the real problem:

  
-- NB: wrap this into a xrnx tool, or the idle thing wont work!  
  
-------------------------------------------------------------------------------  
  
-- delay a function call by the given amount of time into a tools idle notifier  
--  
-- for example: ´OneShotIdleNotifier(100, my_callback, some_arg, another_arg)´  
-- calls "my_callback" with the given arguments with a delay of about 100 ms  
-- a delay of 0 will call the callback "as soon as possible" in idle, but never  
-- immediately  
  
class "OneShotIdleNotifier"  
  
function OneShotIdleNotifier:__init(delay_in_ms, callback, ...)  
 assert(type(delay_in_ms) == "number" and delay_in_ms >= 0.0)  
 assert(type(callback) == "function")  
  
 self._callback = callback  
 self._args = arg  
 self._invoke_time = os.clock() + delay_in_ms / 1000  
  
 renoise.tool().app_idle_observable:add_notifier(self, self.__on_idle)  
end  
  
function OneShotIdleNotifier:__on_idle()  
 if (os.clock() >= self._invoke_time) then  
 renoise.tool().app_idle_observable:remove_notifier(self, self.__on_idle)  
 self._callback(unpack(self._args))  
 end  
end  
  
  
-------------------------------------------------------------------------------  
  
local DESTINATION_PATH = "D:\\Test"  
  
local vb = renoise.ViewBuilder()  
  
local dialog_title = "Realtime Render"  
  
local dialog_content =   
 vb:column {  
 margin = 20,  
  
 vb:button {  
 text = "Render",   
 width = 200,  
 height = 40,  
 pressed = function()  
 OneShotIdleNotifier(0, function()  
 renoise.song():render(  
 { priority = "realtime" },   
 DESTINATION_PATH,  
 function()  
 renoise.app():show_status("Rendering done.")  
 end  
 )  
 end)  
 end  
 }  
 }  
  
renoise.app():show_custom_dialog(  
 dialog_title, dialog_content)  
  

Trick is to call the renderer in the “renoise.tool().app_idle_observable”.

Well, his is one for sure… :)

I’m actually scared of using what Taktik pasted, not sure how to work it into how I tend to put a bunch of commands and functions into one script…

Simply add this pressed snippet across yours in your own button section (note you might need to raise the 0 to 10 or 15 in the first parameter behind the OnShotIdleNotifier call):

  
 pressed = function()  
 OneShotIdleNotifier(0, function()  
 renoise.song():render(  
 { priority = "realtime" },   
 DESTINATION_PATH,  
 function()  
 renoise.app():show_status("Rendering done.")  
 end  
 )  
 end)  
 end  
  

then paste this code at the start of your lua program

  
class "OneShotIdleNotifier"  
  
function OneShotIdleNotifier:__init(delay_in_ms, callback, ...)  
 assert(type(delay_in_ms) == "number" and delay_in_ms >= 0.0)  
 assert(type(callback) == "function")  
  
 self._callback = callback  
 self._args = arg  
 self._invoke_time = os.clock() + delay_in_ms / 1000  
  
 renoise.tool().app_idle_observable:add_notifier(self, self.__on_idle)  
end  
  
function OneShotIdleNotifier:__on_idle()  
 if (os.clock() >= self._invoke_time) then  
 renoise.tool().app_idle_observable:remove_notifier(self, self.__on_idle)  
 self._callback(unpack(self._args))  
 end  
end  
  
  

That’s all.