Disable Audio Interrupt in M4L

andrej's icon

Hi, I have found out somewhere in the forum that M4L by default works with Audio Interrupt on.
Can someone confirm this. Thanks. Anyway if this is true I would like to ask if it's possible to turn it of when working in M4L.

Why I want to do that. Basically because I have a patch that uses Mira and the patch works fine in Max but not in M4L. In M4L there are huge CPU spikes when using Mira and I believe that this is due to the Audio Interrupt behaviour because I was able to reproduce the same overloads in Max when I turned on the Audio Interrupt function.

In general I would like to know more about how Live threads the Scheduler options when Locked inside Live. Thanks.

Any help would be much appreciated. Thanks. AK

andrej's icon

Anyone? THX

andrej's icon

Bump!

Martin Martin's icon

Ok - I had the same problem and found answers, to everyone stumbling like us:

In M4L:
- Audio Interrupt and Overdrive are always activated (https://iainctduncan.github.io/scheme-for-max-docs/s7.html
- Signal and I/O Vectorsize are harcoded/always 64 Samps

This means in M4L there are just two threads to work with: The main thread and the audio thread.
more about threading:
https://cycling74.com/tutorials/advanced-max-learning-about-threading

To lower the CPU load a solution could be to move some messages to the mainthread with the "defer" object. It can easely happen that some messages send in reaction to a midi message end up in the audiothread.
to check the thread of a message use the "min.threadcheck" object, found in the min-devkit package.

The downside of moving timesensitive messages to the mainthread is that with bigger buffersizes in ableton, like 1024 or even 512 there can be major timing issues.

Iain Duncan's icon

There can also be timing issues anytime you move messages to the lower thread if there is a UI activity going on, regardless of buffer size. (ie window redrawing or resizing). I wouldn't recommend moving anything that makes sound to the main thread if you can avoid it! What are you trying to do that is causing issues?

Martin Martin's icon

It's a percussion synth in Gen. I trigger different sounds over Midi Notes.
Each Midi Note corresponds to a UI-Setting that is retrieved over pattrstorage.
Switching sounds causes the cpu to overload.

Midi Note -> Pattrstorage -> Scripted Live-UI (dials & numberboxes) -> Parameters (~90) -> Gen -> Audio Out

It's running super smooth with low latency when i defer the midi note to the main thread and ableton running with 256 Buffersize.

When editing the sound I need the UI, but do you think it would change a lot to send the Parameters directly to Gen.. (in the audio Thread) ? (probably yes :) - And then maybe update the UI over the Main thread..?

Iain Duncan's icon

Without looking at your patch in detail, I would guess your issue comes from going through the UI layer before going back to Gen. It looks to me like you have a chain of high thread to low and back to high, which is potentially problematic. I would recommend finding a way not to have to high the UI thread there. I do something similar in Scheme for Max patches, but have all my settings in an instance that lives in the high thread, and only work to *look* at it goes in the UI thread, and that performs very well. Do you do a screen redraw when you switch sounds? that would be a good clue. HTH!

Martin Martin's icon

By screen redraw you mean if the UI changes when switching sounds? yes it does. While writing about it seems obvious that this might be the first thing to change. :)

I will split the data in an "UI-Thread", aka Main, and an Audio thread.
And also difference between an Edit Mode where the UI will be updated and a Performance Mode with no UI Updates at all.

When editing over the UI the data must be moved in the audiothread though...

//Another thing i couldn't find any reliable information on: Is the UI always "calculated" in M4L, even if it's hidden or even if the track view is not active?

Iain Duncan's icon

Yeah, that is very likely your issue then. If you change the UI, the ui thread does some expensive work and is going to block other work in that thread.

Not sure if you are interested in going down the lisp rabbit hole or not, but I have this kind of thing working very nicely in Live under high loads with low buffer sizes by using Scheme for Max and having a view driver object in my high thread that sets up data structures that the UI elements read. It means all patch control stays in the high thread, and only redraw needs to happen in the low thread. It's working very well for driving quite large UIs while running heavy sequencing. But it's a big rabbit hole! lol


Martin Martin's icon

Yes I just looked at it while searching for solutions and wasn't shure if this could be a solution - but apparently yes ;) I need to finish this project in about 2 - 3 weeks - so...
Do you have some resources, example patches that deal with the use case we discussed in this thread?

Iain Duncan's icon

Unfortunately I don't have examples for this exact use case up yet, so 2-3 weeks could be "ambitious", as they say. Though that depends on your programming experience. I do have tutorials up on the language and could certainly give you some help if it's something you're willing to share in the online cookbook afterwards (or a scaled down example version). Here are the basic tutorials, and feel free to hit me up if you want to try. iainctduncan at the used-to-be-not-evil email service that starts with G. ;-)

https://iainctduncan.github.io/learn-scheme-for-max/introduction.html
https://iainctduncan.github.io/scheme-for-max-docs/

Iain Duncan's icon

I also have a new feature in the cooker to release soon in 0.4. I added a fast static typed array so that one can pass numerical data very quickly between a high and low s4m instance for driving UIs. Will probably get that released in the next month along with a fast and dumb UI grid object I use with it for making tabular/tracker UI views.

Martin Martin's icon

Ok, I managed to implement the idea of 2 dedicated preset systems for each thread with a
-Pattrstorage for the UI Elements
-a Dict for almost the same parameters that drive synthesis
CPU is never over 2% ;)

But I see why Scheme could be a more elegant solution - I will definitively come back to it with the next project and more time to learn it beforehand...
Thanks anyway - you helped me a lot! and probably others that stumble upon this thread...

Iain Duncan's icon

Ah that sounds good. That's sort of what I do (less worrying about the extra thread), in that I use dicts in max/hashtables in Scheme and use them to manage any "patch" elements I want to persist. The s4m to dict interface is pretty good, so that works well. Another thing worth noting is that loading and saving files directly to the file system is easy and fast in s4m. Fast enough that for small patch things I don't usually even bother worrying about deferring it. I was previously pushing to a dict and then saving from the dict in the low priority thread, but now I mostly just save straight from Scheme.

Iain Duncan's icon

And the offer stands on help, I'm always happy to help folks out if they want to contribute some example code to the online resources! :-)