Posted in:

I'm pleased to announce that the first preview builds of NAudio 3 are available on NuGet. I have put a lot of time into this over the past few months, and with the assistance of Claude Code (which I wrote about recently) I've managed to make significant progress.

In this post I want to cover the most important things you need to know about what has changed.

Modernization

The key theme has been to modernize the codebase, including a major rewrite of the interop to use improved techniques such as [GeneratedComInterface] and [LibraryImport]. This meant that we have finally dropped support for the legacy .NET Framework, as well as retire the dedicated UWP assembly. NAudio 3 will require .NET 9 or newer. If you need to run on older versions of .NET you will need to stay on NAudio 2.

Span<T>

Another big change is making Span<T> the primary way that audio is passed around, instead of the previous byte[] buffer, int offset, int count triple that had to be passed everywhere and led to bugs whenever someone forgot that offset might be non-zero. Using Span<T> reduces the amount of copying that is needed and allows us to read directly from unmanaged memory if needed. The main place you'll see this is that IWaveProvider and ISampleProvider now use Span<byte> and Span<float> respectively. Although this is a breaking change, it's one that I'm hoping won't be too disruptive as most NAudio users simply make use of the built-in derived types.

New WasapiPlayer and WasapiRecorder

The recommended approach for audio playback and recording on Windows is through the WASAPI APIs, and although I'm leaving the legacy WasapiOut, WasapiCapture and WasapiLoopbackCapture in place, I wanted to start afresh so there is now WasapiPlayer and WasapiRecorder which replace them, and use a builder pattern. Check out the tutorials WasapiPlayer and WasapiRecorder to see them in action. I'd recommend moving across to them for new development - we'll probably keep the old classes in place for one more major version to ease the transition.

New AsioDevice

Similarly with ASIO, the old AsioOut class which had an ugly InitRecordAndPlayback for duplex playback and recording is essentially retired in favour of a new AsioDevice which aims to simplify the three most common use cases - playback only, record only, and duplex mode - each has a dedicated method (InitPlayback, InitRecording and InitDuplex). Check out the tutorials AsioPlayback, AsioRecording, and AsioDuplex for examples of these in action. I'm particularly pleased that NAudio is now in a much better place to support low-latency audio - which was always a dream of mine since I started the project.

Legacy WinMM and DMO

The WinMM and DMO parts of NAudio are still present, but considered "legacy" now, and hosted in their own Windows-only NAudio.WinMM and NAudio.Dmo assemblies. I did some renaming. The oddly named WaveInEvent and WaveOutEvent which became the recommended recording and playback options for WinMM are now renamed to WaveIn and WaveOut. The old WaveIn and WaveOut are still present but renamed to WaveInWindow and WaveOutWindow and live in the NAudio.WinForms assembly as they depend on window handles for their message callbacks. DirectSoundOut has been rehoused into NAudio.Dmo and should also be considered legacy.

Linux Support with ALSA and libsndfile

One very exciting announcement is that NAudio finally supports playback and recording on Linux thanks to a community contribution that I reworked with the help of Claude into the style of NAudio 3. Use NAudio.Alsa for audio playback and recording on Linux. And on top of that NAudio.SoundFile wraps libsndfile which itself is a cross-platform library that can read and write a wide variety of audio file types. This not only brings support for these file types to Linux, but also to Windows and macOS. I have limited ability to test on Linux, so this part of NAudio should definitely be considered "preview". I'd love to hear if you have any success using this.

WinRT-based MIDI

There are also new WinRTMidiIn and WinRTMidiOut that provide MIDI in and out using the more modern WinRT APIs (although these soon may be superseded by a newer MIDI API Microsoft are working on). For the time being these classes live in NAudio.Wasapi.

Improved test harnesses

With so many big changes, I needed to ensure I had a quick way to check things weren't broken. The WinForms (NAudioDemo) and WPF (NAudioWPFDemo) projects both have had significant improvements to give me an easy way to drive many key NAudio features. And there is now also NAudioConsoleTest, which is a terminal-based testing tool that supports scripting as well as menu-based navigation of the various test scenarios.

Bugfixes

I've also spent a huge amount of time trying to revisit as many open issues and PRs as possible. There were almost 500 open issues and I've responded to over 150 of them now. Many of these have resulted in bug fixes and enhancements. I've still got a very long way to go though, so thank you for your patience and apologies to everyone who never got a reply to their question.

What's Coming Next?

Although I don't want to rush NAudio 3 out before it's ready, at the same time I don't want to delay it too much by implementing every idea I have. One very exciting thing in the works is a library of effects (think reverb, delay, compressor, etc.). I have a great demo where you can run them in real-time using ASIO - great for setting up a guitar effects chain. That's not too far from being ready (although again the first drop of effects should be considered "preview" quality).

Another very ambitious idea I have is to implement VST3 hosting. I've made very good progress on this, although there is a long way to go still, so that might not make it in. Even more stretch goals I have are for NAudio to ship with a basic synthesizer, sampler and sequencer - finally implementing three of the things I most wanted to create with NAudio when I first started it - but each of those is a major undertaking in its own right.

I'm not sure if the public API is going to change much more. One idea I had was to replace WaveFormat with something less tied to the Windows WAVEFORMATEX structure and so experimented for a while with an AudioFormat base class. However, the change ended up being quite disruptive so that might be something to revisit for NAudio 4 to give me more time to properly think through what the best design would be.

Similarly, I've wanted to address the challenges of dealing with both repositionable WaveStream and non-repositionable IWaveProvider/ISampleProvider instances. There are a few ideas I have to improve things, and one option is to use the new audio effects framework as a solution - allowing people to insert a chain of audio effects into a WaveStream which could give the best of both worlds. This will need some more thought though as it's a potentially disruptive change so I want to get it right.

One thing that's not on the agenda at this time is macOS audio playback as I don't have a device to test on. If I ever get one, that would certainly be one of the first things I'd want to try on it!

Try it yourself

Anyway, I'd love for you to try the NAudio 3 preview libraries for yourself by downloading them on NuGet. In the NAudio repo there are short doc tutorials for many of the new features (e.g. ASIO duplex, Linux playback with ALSA, and cross-platform audio files with libsndfile).

Want to get up to speed with the the fundamentals principles of digital audio and how to got about writing audio applications with NAudio? Be sure to check out my Pluralsight courses, Digital Audio Fundamentals, and Audio Programming with NAudio.