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
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ā
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.
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
What to upgrade to a higher version of Lua or LuaJIT.
This is my wish for the next version of Renoise.
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.
Hello,
there is video with āno gui lockā.
Everything works as it should and as I imagine, but the speed
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()
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
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