NAudio Performance

Nov 12, 2012 at 8:28 AM

Hey,

Thanks for your awesome work. It's been rather enjoyable using your library for development. I have a question about performance, however. My intention is to create a Digital Audio Workstation with VST support (using VST.NET) and I would like to be able to sell it as a full-featured, powerful program. Will NAudio support dozens of audio tracks playing simultaneously? What about with the overhead of VST processing? Am I overestimating the performance of .NET, and should I instead be writing this in C++? Performance does matter. People recording instruments need very low latency between recording and playback otherwise... well, recording gets very confusing at that point. I need to accomplish a latency of no more than 20ms.

Should I re-think my approach?

Thanks!

Nov 12, 2012 at 12:28 PM

.Net is plenty fast enough to do a project like that, *IF* you correctly optimize the code (using the profilers as guides).

That said, I would recommend only opening a single output stream; This uses less handles and allows you to mix on the fly in your own code.  I'd also recommend that you make sure all sources use the same sample rate as the output stream (we'll assume all of them are 32-bit float internally).

No matter which language you use, this will be a large project...  take your time and make sure you are always using the best algorithm for each piece of the system.

Good Luck!

Coordinator
Nov 14, 2012 at 6:10 AM

the big problem with .NET for very low latency is the garbage collector. When it kicks in it stops all threads from running and that can cause audio output glitches. There are some best practices for writing audio code in a way that reuses buffers so the garbage collector has less work to do, but unfortunately you have almost no control over exactly when it will run.

Also, only the ASIO and WASAPI output modes are able to work at low latencies. WaveOut and DirectSound won't go much below 50ms.

NAudio hasn't been extensively optimised for very low latency, so you might also need to fine tune some classes if you are serious about doing this.

To make a full-featured DAW that competes in an already crowded market is a very big undertaking, so I suggest you start by creating some smaller audio applications first.

Mark

Nov 14, 2012 at 6:30 AM

Would you recommend temporarily setting GCSettings.LatencyMode to GCLatencyMode.LowLatency temporarily while playback is being done? I set the latency mode back to what it was previously when the audio is paused or stopped. Apparently this setting suppresses garbage collection completely except for in very low free memory situations, which sounds great as long as my code for playing audio is very clean. What's your opinion on the matter?

Coordinator
Nov 14, 2012 at 6:47 AM

that's interesting. LowLatency mode has been on my list of things to experiment with for some time, but I haven't got round to it yet. It it does work like that, that will be excellent for audio. You could also do a collect before playback begins.

Nov 14, 2012 at 6:52 AM
markheath wrote:

that's interesting. LowLatency mode has been on my list of things to experiment with for some time, but I haven't got round to it yet. It it does work like that, that will be excellent for audio. You could also do a collect before playback begins.


It would actually be great to have this built into version 1.7. They recommend that you use Constrained Execution (http://msdn.microsoft.com/en-us/library/ms228973.aspx) and limit the code that runs with low latency mode enabled to a try/finally block. This could be done in the NAudio processing thread, because often Play() and Stop() are not called from the same method. I would recommend the SustainedLowLatency actually. Glad I could pique your interest on the matter.