Scrolling and general GUI operations causing audio dropouts and timing issues
I am getting significant audio timing issues when scrolling vertically in the patch or doing other gui related actions.
The timing of the beat in the attached patch gets messed up every time I open some gui element in Max or even if I just quickly scroll vertically in the patch. For example opening images or snippets from the left sidebar causes big audio/timing dropouts too. The same goes for removing insignificant objects from the patch like comments.
I tried to tweak the scheduler settings (give gui the least amount of priority as possible) but without any success. Activating SIAI also didn't help. I would even say it made things somewhat worse.
Precise timing is an absolute priority for me and no action with the patch must interfere with it. I can handle slow gui provided the timing stays rock solid.
How can I solve this?
Please, see the attached patch.
Thank you very much.
Here are my current settings:
{
"version" : "Version 8.1.10 (f1acba9) (64-bit windows)",
"platform" : "windows",
"arch" : "x64",
"osversion" : "Microsoft Windows 10 Professional (build 19041), 64-bit",
"samplerate" : 44100,
"iovs" : 64,
"sigvs" : 64,
"scheduler_in_audio_interrupt" : "on",
"audio_drivername" : "ad_asio",
"audio_driver_subname" : "AudioBox ASIO Driver",
"license" : "permanent full",
"machine_id" : "f3eb494729c2e86f555b7b24b50332d2",
"eventinterval" : 2,
"schedinterval" : 1.0,
"overdrive" : "off",
"pollthrottle" : 40,
"queuethrottle" : 100,
"sysqelemthrottle" : 1000,
"refreshrate" : 33.333332061767578,
"schedslop" : 25.0,
"eventprobing" : 0,
"mixerparallel" : "off",
"mixercrossfade" : 0,
"mixerlatency" : 30.0,
"mixerramptime" : 10.0,
"videoengine" : "viddll",
"glengine" : "gl2",
"packages" : {
"BEAP" : "1.0.3",
"bonk~ v1.5" : "",
"CNMAT Externals" : "1.0.4",
"CNMAT MMJ Depot" : "3.1.0",
"ease" : "1.1.1",
"hap" : "1.0.6",
"imp.push" : "",
"jit.mo" : "1.1.2",
"jk.push 2" : "2.0.2",
"link" : "1.2.6",
"Max ToolBox" : "15",
"max-mxj" : "7.2.5",
"maxforlive-elements" : "0.3.7",
"Mira" : "1.2.1",
"ml.star" : "1.2.1",
"Node For Max" : "1.3.3",
"p2d" : "",
"PeRColate" : "1.2.0",
"Sadamlib" : "",
"VIDDLL" : "1.2.4",
"Video & Graphics" : "7.2.0",
"Vizzie" : "2.1.4"
}
}As you can see from this excerpt of this cpuclock-based-timer-connected-to-metro log, the issue is non-trivial (values in ms). This was logged while scrolling vertically up and down in the patch. These are massive timing inconsistencies which are unacceptable:
print: 102.959900
print: 88.684200
print: 110.457200
print: 101.839000
print: 86.376100
print: 99.647000
print: 113.559000
print: 86.709000
print: 108.428200
print: 104.473500
print: 85.729300
print: 110.010000
print: 104.214400
print: 85.434900
print: 99.644300
print: 114.411000
print: 85.731400
print: 102.369500
I have also realized that I don't even have to run audio in order to reproduce the issue. I can still log the same inconsistencies when running the patch with audio disabled and scrolling vertically.
EDIT:
OK, nevermind. Without audio the timing of the metro can get precise enough when using Overdrive. So that's good.
So I think I can narrow this down to audio domain. Dropouts when operating with GUI. Any tips how to prevent that from happening?
I have renamed the thread so that it more describes the issue.
Hi, Baek. In my opinion, this is one of the most frustrating things about Max. In most cases, the GUI drawing really should be done in a separate thread. It's even worse when dealing with Jitter, as Jitter operates in the same thread as the GUI drawing, lending to drop frames because of it.
Anyway, I've tested your patch and identified that the problem lies in the GUI of the playlist~ object, not before. If you replace the playlist~ with a sfplay~ object, it works well.
I've also noticed that if you maximize the window size, when scrolling, even though there's no objects to be drawn on the right side, the timing gets worse than if you have a small window.
Hi Pedro, thank you for the response. I am glad I am not alone in this. It baffles me why would Max be programmed in such a way but it is what it is I guess. To be honest I would much rather have Max 8 (with all the features) in PureData graphics. Lightweight and reliable.
Unfortunately I am unable to notice much difference in the example you have provided. But in theory it makes sense I think because sfplay~ object has less graphics to render than playlist~. It's a workaround that will be very CPU dependent. One will probably notice improvements on some machines and less improvement on others. Will keep this in mind though - "avoid fancy visuals at all costs".
What actually made a difference in my patch was removal of the metro as a master clock altogether and replacement of it with [count~] -> [>~ 0] -> [edge~]. Together with SIAI I've got a pretty tight results on my machine. I will probably have to operate in the signal domain as much as possible if I want to have the timing tight. But that's a giant learning curve for me at the moment so the project will take much more time than expected.
I will be also keeping any visual stuff in patch to the absolute minimum and strictly deferred if possible.
This issue kind of took away my freedom in Max environment to be honest. I am now afraid to touch anything in non-signal domain when patching which limits me and complicates my patching a lot. I would hate to program stuff for weeks only to discover it's not scalable into larger patches because of timing issues...
But isn't it strange that [count~] -> [>~ 0] -> [edge~] is much more stable than [metro]? Both [edge~] and [metro] must output their bangs into data domain. How come [metro] is so prone to performance issues connected to GUI rendering and [edge~] isn't? Is there a design flaw in [metro]?
Sorry Pedro, I have messed up my testing.
You are absolutely correct. There is indeed a huge difference between playlist~ and sfplay~. I just had my SIAI accidentally disabled when testing your patch! It's a night and day difference. Thanks a lot for this.
And that [count~] -> [>~ 0] -> [edge~] doesn't actually seem to do any difference in timing of data messages. My testing was wrong. Sorry for all the confusion.
I have summarized the findings in an altered version of your example patch. See if you can reproduce my results:
As you can see in the signal domain example in that patch, the difference between playlist~ and sfplay~ seems to completely disappear. I don't understand why though... I would expect playlist~ to be worse in all situations but maybe it internally handles signal of 1 differently than data value of 1.