Improving DAW compatibility

Captain's Log: Stardate 78294.1

DAW Licenses for Testing

After releasing the pre-alpha version 0.0.8, I got feedback that Anukari was crashing as a plugin in Bitwig. This reminded me that I hadn't done a detailed check on DAW compatibility/stability in a while, so I sat down to do that.

The last time I did this was in the first week after starting the pre-alpha, and I did it by installing the free trials for a bunch of DAWs. Unfortunately, in the intervening 6-8 weeks, all of the free trials had expired. So, for example, I was hosed in terms of debugging the Bitwig crash locally.

So I decided to email the top 10 or so manufacturers for DAWs that I'd like to test against, and asked them if they would give me a free copy of their DAW for this purpose. I'm not sure exactly what I expected to happen here, but I definitely didn't expect for them to universally say "yes," which is what happened. So far, every manufacturer that's responded has not only given me a license key, but given me a key for their top-of-the-line product with all the extras. For example, Reason Studios not only gave me Reason 13, but also unlocked their entire line of plugins. Which is incredibly generous, and also unnecessary. But I won't complain.

It turns out this is a normal thing in this kind of industry, and there's even a special kind of license for it: "Not for resale" (NFR). Which makes sense; given the purpose of the license it would be ridiculous to go off and resell it.

Anyway, this is great news, as I now have 13 of the most popular DAWs installed on my Windows development machine, and after some work, have gotten Anukari working in all of them with no crashes. I haven't installed them on MacOS yet but I'll do that soon as well.

The Most Fun Compatibility Bug

The crash in Bitwig was somewhat interesting. What was happening is that Bitwig actually initializes the DAW GUI before it has created a native window for it to draw in, and my code was assuming that a native window would be available at that time. Fixing this just required using JUCE's parentHierarchyChanged() method to watch for changes until the native window became available.

The more fun bug was the crash in Cakewalk Sonar. Pretty quickly I figured out that the crash was happening when Anukari called SymInitialize(), which is a Windows API function that you can use to include symbols in crash logs, which makes them vastly more usable. This function has the user-friendly property that if you call it twice in a given process, it crashes on the second call. It's a bit surprising to me that Cakewalk is the first DAW I've run into that calls this function, since it's quite useful, but it is.

The obvious thing to do is for Anukari to somehow check whether SymInitialize() has been called and don't call it. But I read through the Windows docs and didn't find any way to do this, and Mr. ChatGPT stated very confidently that it was not possible. Still, I wasn't convinced and kept Googling, and eventually found this tweet from my programming hero Jonathan Blow (the creator of the amazing video games The Witness and Braid). His initial tweet summed up my frustration over the impossibility of the situation, but someone eventually replied with a solution, which is to call SymEnumProcesses ().

Now, this is a damn sight better than blindly calling SymInitialize(), which guarantees a crash if the DAW already called it (like Cakewalk Sonar). But... it's still technically impossible to do it safely. This is because calling SymEnumProcesses() concurrently from two threads is not safe, and of course Anukari has no way to know whether any other thread running in the DAW might call it. Still I went with this solution, because it is unlikely that anyone else is calling this function, and if they are, it's unlikely that it is concurrent with Anukari, and even if so, Anukari is calling it in a read-only kind of way, so maybe it wouldn't crash anyway. Hopefully. :)


© 2024 Anukari LLC, All Rights Reserved
Contact Us|Legal