46 posts / 1 project
Sound Engineer / Programmer
[HELP ?] NSView and VST plug-ins
10 months, 2 weeks ago
Hey Cocoa masters and VST Gurus out there !
I encountered a problem while working on the save system of Top !, that you might be able to help with :
When loading a save file, I want to display a progress bar while all the cuelist parameters and audio files are restored. To do so I create a thread where I do all the loading task, which updates a progress counter, and I draw the progress bar according to that progress counter in the main thread.
Bad things happen when we want to recall VST plug-ins. Some of them seem to create an NSView for their GUI as soon as they are instantiated. Thus when we are back in the main thread, and we try to open a plug-in editor window, it may crash or be blank, or even hang the whole GUI, whereas if a plug-in is created on the user's request once the cuelist is loaded (ie. on the main thread), it's all fine.
My understanding is that all the code involving drawing in an NSView has to take place in the main thread, as Cocoa's doc explicitly states that NSView is thread-unsafe and that it should be created in the main thread only.
For now my workaround is to split the loading process into a multi-threaded part that parses the save file and loads all audio files while updating the progress bar, and a second pass that restores plug-ins in the main thread. Hopefully the most intensive part (loading audio) doesn't freeze the UI, and the plug-ins creation is fast enough to be unnoticeable. But it's not guaranteed that any particular plug-in will be fast enough. Like it could go totally crazy and check for dongles or load audio samples, who knows ? Or it could crash, or hang. And it would freeze the UI with no hope of recovery.
Is there a way to get plug-ins created in a separate thread an still use their GUI in the main thread afterwards ? Do you know how other VST hosts handle recalling plug-ins without temporarily freezing ? Or is there any obscure secret magic to get an NSView to be drawn from outside of the main thread ? More generally speaking, how do you typically handle time-consuming operations like loading/saving big files, etc, while keeping the GUI active ?
Any thoughts much appreciated !