What’s the correct way to load a (pure) Lua library inside a Phrase script, if possible?
I would like to organize some util modules to be reused in my scripts, but I haven’t figured out how to achieve it.
PS: And how to print debug messages?
What’s the correct way to load a (pure) Lua library inside a Phrase script, if possible?
I would like to organize some util modules to be reused in my scripts, but I haven’t figured out how to achieve it.
PS: And how to print debug messages?
Unfortunately, you cannot load libraries currently AFAIK.
There is no built-in debug console for this but if you start Renoise from a terminal you will see messages of print
showing up there, at least this does work for me on Linux.
prints
do work in https://pattrns.renoise.com/ though. They are disabled in Renoise to avoid overhead in the realtime audio thread where the scripts run.
Unfortunately, you cannot load libraries currently AFAIK.
Ouch! I really hope this will be supported in the future…
I suppose this will require the scripting engine to support communication and code execution on the GUI thread.
This was left out on purpose.
Right now, everything you do in the phrase scripts is portable and self-contained.
Once we allow requiring external scripts, a song or instrument will depend on externally defined scripts and files. This is nice to have while creating new content but a problem when you want to share your stuff or want to continue working on your own songs.
So IF there is some kind of support for externally defined libraries, they must be managed and saved within the Renoise song or instrument.
And this “how” and “where” to manage such external content in the instrument is where we’ve been unsure, so this didn’t make it into this release.
For now, you can simply duplicate code by copy-pasting it into your scripts.
Also note that all this stuff is highly performance critical. It’s running the audio engine in real-time. You don’t really want to load shared libraries that open files or do socket connections there.
I get all your points. And yes, in case shared modules should be stored inside the project for portability.
Of course, care is required to do not abuso of the audio thread. It might be left to the user to decide how much to stretch it. Other kind of fences are tricky to implement (block the loading of certain APIs, etc.).
A much more complex solution (like audio plugin frameworks do) is implementing the communication between the audio thread and GUO thread…
Technical question out of curiosity: did you ever run into GC-related stutters in testing? It feels like script phrases could potentially generate a lot of garbage if you’re running many at once. I’ve never used LuaJIT and I trust its performance is great, but it is slightly nervewracking to think about.
The engine behind Phrase Scripting runs natively, it’s compiled from Rust code and has no GC. The lua parts does have GC but lua uses incremental GC that doesn’t work in a way where it would wait for all the garbage to accumulate then take over the program to clean it all (which tends to be the main cause of stutter when it is about GC), instead garbage is more continuously cleared in smaller steps.
At least this is my understanding. A typical sketch here won’t generate much garbage anyway, when it does, it is cleaned gracefully and a large part of the memory is manually managed.
If you are worried about stutters in a live scenario, try doing some stress testing on your machine with a bit more scripts than what would be realistic for you to run in a performance.
I think that kind of incremental GC is still nondeterministic. But this jives with my feeling that even if it’s a theoretical problem, it’s not likely a practical one. I was mostly just curious as I’m interested in this field in a general way. I’m not currently relying on the engine to be perfect, though I think I’d probably trust it if it came down to that.