How to let renoise breathe

Hello,
How do I ensure that Renoise can rest between long calculations, restore the gui, etc.?
is there anything in the API? Any interruptions?
Or will lua coroutines help?

local result = 3
while result ~= 0.0001 do
      -- here comes renoise rest function
      result = loooong_run()
end

thanks

Look into the standard tools pack, I think “com.renoise.ExampleToolSlicedProcess.xrnx” contains an example of how to do background processing, look into “process_slicer.lua”

1 Like

Thanks.

Nice solution,
but how should I wait for the end of the process ?
Maybe i’m overworked but this is a Catch-22 for me right now.
I need wait for result.

local process = ProcessSlicer(long_calc)
process:start()
-- here wait for result from long_calc
-- don't leave until result is known
while process:running() do
    -- Catch-22 here
end

I think there is no way to yield a thread waiting for such a thing to finish. How you would want to solve it probably depends on how you built your program. If it is a tool that gets triggered somehow to do a job, maybe it would be a good idea to split the processing, into prepare (what gets triggered by ui or key combo), and that starts the slicer, then when your sliced function has finished, it could just call the code that is needed to finish the job after the calculations. No expert on this, maybe someone else knows more about it.

anyway thanks for pointing me in the right direction

1 Like

Sorry but I have to share this.
I finally worked out a method to let Renoise take a breather from the calculations.
I used, of course, a slightly modified ProcessSlicer.
Only now after some measurements I’m shaking my head in disbelief.
I do have a concept where Renoise won’t stop, but at such a terrible price.
In the bubble generator, without ProcessSlicer I generate 3009 bubbles in 2.01s, while with Slicer in 160s !!!
30243 Bubble in 19s without slicer with one click, I don’t even measure with Slicer.
I wanted to use it in ADrums, BubbleGen and others but like this :frowning:
What to upgrade to a higher version of Lua or LuaJIT.
This is my wish for the next version of Renoise.

2 Likes

Just a suggestion for an approach…

Maybe something is very suboptimal with the good old slicer, and it’s better making a custom one. Make a table where you have a queue, and make it so that each entry is a definition of processing x number of bubbles. Let app_idle_observable munch them one at a time. Before every new entry being processed, Renoise should have time to do whatever it wants for a smooth ride + the penalty shouldn’t be very high. That’s what I imagine.

1 Like

IMO Renoise should manage this by itself. Or running the Lua stuff in a separate thread next to GUI.

1 Like

Hello,
there is video with ‘no gui lock’.
Everything works as it should and as I imagine, but the speed :frowning:
As I wrote, I use the standard ProcessSlicer (nothing could be simpler) but I just supplemented it with a function that should be executed at the end of the coroutine.
In this case, when the calculations are finished, the sample is drawn.
I added a progress meter for clarity.

I think it couldn’t be simpler, but I’m happy to learn. This is the only thing that separates me from much more complex things.

My simple Coroutine function.

local function go()
    local start = 1
    local bubble_rate = self.vbs.bubbleInSec.value / self.samplerate
    while start < samples do
        self:PreRender(start, samples)
        start = floor(start + self:Next(bubble_rate))
        vbs.progress.value=start
        coroutine.yield()
    end
    self:DeclickIn(self.vbs.declickIn.value * self.samplerate)
    self:DeclickOut(math.floor(self.vbs.declickOut.value * self.samplerate))
    if self.vbs.normalize.value == 1 then
        self:Normalize()
    end
    vbs.process_gui.visible=false
end
    
local process = ProcessSlicer(go, RenderSample)
process:start()
2 Likes

I don’t know if this will help you, but the idea is clear: “do it later”.

You can use a timer to run a function at any time you want, instead of it being one process followed by another that just finished. This creates a pause between processes that allows Renoise to run whatever it is doing without hindrance.

You can do this with the timer at the end of the entire process loop of the slicedprocess…

I tried to solve it using coroutines where I put the creation of each bubble into a separate thread. I keep these threads in a table but sometimes I still have to check the states.
If I overdo it, there are sometimes 36k threads :slight_smile:
But this is a good idea.
I will try to put this control in the timer and not in the idle function.
Now my dispatcher function for thread looks like this.
I need to remove cpu intesive while function.
If i put only ‘for’ cycle to timer, so it might work.
If all bubbles are done then render.

function Bubble:Dispatcher()
    vbs.process_gui.visible = true
    while true do
        local n=#self.bubble_threads
        if n==0 then break end
        vbs.progress.value = vbs.progress.max - n + 1
        for i=1, n do
            local status, res = coroutine.resume(self.bubble_threads[i])
            if not res then
                table.remove(self.bubble_threads, i)
                break
            end
        end
    end
    vbs.process_gui.visible = false
end
1 Like

man this was the kick I needed.
It works flawlessly using timer !!!

2 Likes

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.