Today I spent some time looking into why Cantabile 3’s user-interface sometime felt a bit unresponsive — especially while loading sessions or starting/stopping the audio engine. I ended up making some non-trivial improvements to the interactions between the UI and the audio engine — and the resulting improvement is significant.

The Problem

One of the key goals with Cantabile 3 was that the audio engine never be interrupted by the user-interface. To make this happen the user-interface sends messages to the audio engine which picks them up on the next audio cycle. In the meantime the user-interface waits until the audio engine flags the message as processed. That’s all well and good, except it means the user-interface can become laggy if it needs to send a lot of messages.

To emphasize the problem I setup a session with 4 instances of Kontakt (each with 64 audio output channels) and an audio engine buffer size of 2048. Looking at the log, you can see the undesirable results:

That last line tells the story: 272 calls to the audio engine for a total elapsed time of almost 13 seconds.

The Solution

In Preview 1 I used a couple of strategies to try and mitigate this problem but they were getting overly complex so today I took a fresh look at the problem. The solution I decided on was to setup the communication in such a way that for most scenarios the user-interface doesn’t need to wait for the audio engine to complete its work.

This required quite a bit of reworking — especially in handling the shutdown/deletion of objects. It also took a couple of hours in the debugger but the result is worth it:

Much better. Those 5 remaining calls could also be cleaned up but I’ve left them for the moment as a precaution to ensure objects aren’t deleted while still in use by the audio engine.

Switching back to a normal audio buffer size and turning off the console logger results in a total time of about 50ms — and the UI feels much snappier.

Other Improvements

Preview 2 will also see some other improvements to the audio engine:

  • Improved handling of an unresponsive audio driver — which was causing problems with some audio drivers.
  • A new non-blocking memory manager was introduced to implement some of the VST 3 support. Although VST 3 support has been abandoned for now, the new memory manager lets me simplify some other code and makes the above messaging improvements possible.

Preview 2 Coming Soon

These changes will almost certainly be in Preview 2 which is just about ready. It’s a bit risky because I’ve had to make a lot of changes, but the whole point of these preview builds is to get the engineering right and get it well tested as early as possible.