NAudio 3 is a major release. The single NAudio assembly is now split into
focused, independently usable packages; the minimum target framework moves to
net9.0; the core is cross-platform and Native-AOT compatible; and several
large new subsystems — a cross-platform effects suite, a software sampler, VST 3
hosting, and ALSA and libsndfile backends — join the library.
Upgrading from NAudio 2? Migrating from NAudio 2 to NAudio 3
walks through every breaking change with before/after code. Most apps need only
re-target to net9.0, rename WaveOutEvent to WaveOut, and adjust custom
providers to the new Span<T> Read signature.
Packages and platform
- Minimum target framework is now
net9.0— legacy .NET Framework and .NET Standard 2.0 support is dropped NAudiois now a set of focused packages:NAudio.Core,NAudio.Midi,NAudio.WinMM,NAudio.Wasapi,NAudio.Asio,NAudio.Dmo,NAudio.WinForms, plus the newNAudio.Effects(shipped inNAudio.Core),NAudio.Sampler,NAudio.Vst3,NAudio.AlsaandNAudio.SoundFile. TheNAudiometa-package still pulls the Windows stack together, so existing consumers see no change. SeeDocs/Architecture/NAudio3AssemblyLayoutPlan.mdNAudio.Core,NAudio.Midi,NAudio.Wasapi,NAudio.Dmo,NAudio.Sampler,NAudio.SoundFileandNAudio.Alsaare Native-AOT compatible (IsAotCompatible=true), enforced in CI byNAudioAotSmokeTestNAudio.Wasapitargets plainnet9.0(Windows-only at runtime via[SupportedOSPlatform("windows")]), so cross-platform apps can reference it and build on Linux/macOS withoutEnableWindowsTargeting. The WinRT MIDI backend moved toNAudio.Midi, which now dual-targetsnet9.0;net9.0-windows10.0.19041.0(#1384)- The
NAudio.Uappackage is removed — useWasapiPlayerBuilder/WasapiRecorderBuilder - Packages ship with SourceLink,
.snupkgsymbol packages and an embedded SPDX SBOM
New capabilities
Each new subsystem has its own tutorial or README; only the headline is listed here.
- Audio effects — a cross-platform
NAudio.Effectsframework:IAudioEffect/EffectSampleProvider/EffectChainwith click-free bypass, dry/wet mix and an optional parameter model, plus a broad effect set (EQ and filtering, dynamics, saturation/lo-fi, delay and modulation, reverb including FFT convolution, pitch shifting, and voice-comms AGC/noise suppression). See Docs/AudioEffects.md - Modern WASAPI — high-level
WasapiPlayer/WasapiRecorder, built viaWasapiPlayerBuilder/WasapiRecorderBuilder:IAudioClient3low latency, MMCSS thread priority,IAsyncDisposable, zero-copy buffers, per-process loopback capture, automatic stream routing that follows the default endpoint (#942), acoustic-echo-cancellation reference control (#1223), communications mode, raw mode (#476), and resample-free bit-depth/channel adaptation in exclusive and low-latency modes. See Docs/WasapiPlayer.md and Docs/WasapiRecorder.md - Modern ASIO — a new
AsioDevicereplacingAsioOut: explicit playback/recording/duplex modes, non-contiguous channels, per-channelSpan<float>callbacks, driver-reset recovery and per-buffer timing.AsioOutis preserved as a facade. See Docs/AsioMigration.md - Cross-platform audio files — new
NAudio.SoundFilepackage: read and write WAV/AIFF/FLAC/Ogg-Vorbis/Opus/MP3 via a system libsndfile on Windows, Linux and macOS (the first cross-platform FLAC/Vorbis/Opus encoder in NAudio). See Docs/CrossPlatformAudioFilesWithSoundFile.md (#1289) - Linux audio — new
NAudio.Alsapackage:AlsaOut(IWavePlayer) andAlsaIn(IWaveIn) plusAlsaDeviceEnumerator, backed bylibasound. See Docs/PlayAudioFileLinuxAlsa.md and Docs/RecordAudioFileLinuxAlsa.md (#1182) - VST 3 hosting — new
NAudio.Vst3package (Windows-only): discover, load and host VST 3 effects and instruments, with parameters, state and.vstpresetpresets, native editor windows, program lists/units, latency compensation, and live/offline MIDI-file playback through the shared MIDI pipeline. See theNAudio.Vst3README andDocs/Architecture/Vst3Hosting.md. VST is a registered trademark of Steinberg Media Technologies GmbH - Software sampler — new
NAudio.Samplerpackage: polyphonic, cross-platform playback of SoundFont (.sf2) and SFZ instruments and single-sample instruments, rendered as anISampleProvider(SF2 modulator engine, DAHDSR envelopes, LFOs, modulated filters, reverb/chorus sends, voice stealing, choke groups). See Docs/Sampler.md - Event-based device notifications —
MMDeviceEnumerator.CreateNotificationClient()returns anMMDeviceNotificationClientexposingDeviceStateChanged,DeviceAdded,DeviceRemoved,DefaultDeviceChangedandPropertyValueChangedas ordinary events, so callers no longer implement a COM interface or manage CCW lifetime (#1395) - MIDI —
NAudio.Midi's portable leg is now cross-platform; new WinRTWinRTMidiIn/WinRTMidiOutand backend-agnosticIMidiInput/IMidiOutput; and a newIMidiInstrumentseam (MidiFileSequence/SequencedMidiPlayer/OfflineMidiRenderer/LiveMidiInstrument) giving an end-to-end MIDI-file → audio pipeline that drives the sampler or a hosted VST 3 instrument.MidiFilealso reads RIFF-RMID (.rmi) files (#1236) andMidiFile.Exportgains aStreamoverload, thanks to @MaKiPL (#499) - Sequencing — a portable
NAudio.Sequencingnamespace inNAudio.Core(tempo and time-signature maps, transport,EventTimeline, swing, and a sample-accurate per-buffer dispatcher) underpinning MIDI-file playback and the sampler. SeeDocs/Architecture/Sequencing.md - Live capture mixing — new
NAudio.ExtrashelpersCaptureMixerInputandRealtimeCaptureMixercapture and live-mix several sources with different sample rates and channel counts (e.g. microphone + system loopback) into one wall-clock-paced stream. See Docs/MixMicrophoneAndSystemAudio.md (#761) - Reading audio from streams —
AudioFileReaderandCachedSoundgainStreamconstructors, detecting WAV/AIFF from the contents and delegating anything else to Media Foundation, so embedded or in-memory audio plays without a temp file (#927, #963).StreamMediaFoundationReaderalso gains optionalcontentType/originNamehints and Ogg container sniffing (#952) - WAV chunk model —
WaveFileReader.Chunkswith anIWaveChunkInterpreter<T>extension point and built-in interpreters for cue lists, BWFbext(BroadcastExtension, now read and write, with v2 loudness) and LIST/INFO (InfoMetadata);WaveFileWritergainsAddCue,WriteCueList,WriteBroadcastExtension, arbitraryAddChunkand RF64 promotion viaWaveFileWriterOptions(#1013) - Latency reporting — new
IWaveLatencyinterface inNAudio.CoreexposingAverageLatency/CurrentLatencyfor A/V sync and drift detection, implemented across the playback and capture classes (#601) - Sample providers and DSP — new
ChannelMixerSampleProviderwith ready-madeChannelMixMatrixroutings, thanks to @antiduh (#982); a newFftProcessor;Span<T>overloads across the codec/DSP surface; reusable building blocks (EnvelopeFollower,DelayLine,Lfo,Oversampler,LinkwitzRileyCrossover,PartitionedConvolver, …); plus improvements toSmbPitchShiftingSampleProvider(#922),AdsrSampleProvider(#671) andFadeInOutSampleProvider(#1136) - WaveFormatExtensible — new constructors for SubFormat, valid-bits-per-sample and channel mask, readable
ValidBitsPerSample/ChannelMask, and a[Flags] Speakersenum for building channel masks (#1325) - WASAPI sessions and devices —
AudioSessionControl.SetDuckingPreference(bool)(#760);WasapiPlayer/WasapiRecorderexposeDeviceIdandDeviceFriendlyNamefor the active endpoint (#681)
Breaking changes
The full upgrade walkthrough — every breaking change with before/after code — is
in Migrating from NAudio 2 to NAudio 3. The
highest-impact changes:
- Minimum target framework is now
net9.0(legacy .NET Framework / .NET Standard 2.0 dropped) IWaveProvider.Read/ISampleProvider.Readnow take a singleSpan<byte>/Span<float>(was buffer/offset/count) — callers migrate viasource.Read(buffer.AsSpan(offset, count)); implementations override the span methodWaveOutEventis renamed toWaveOutandWaveInEventtoWaveIn(the old names remain as[Obsolete]subclasses).WaveOut/WaveInnow default to event-driven callbacks; the window-based variants areWaveOutWindow/WaveInWindowinNAudio.WinForms, andWaveCallbackInfo/WaveCallbackStrategyare removedWaveOut.DesiredLatencyis replaced byBufferMilliseconds, which sizes each individual buffer rather than the total across all of them.WaveIn's default record format changes from 8 kHz mono to 44.1 kHz stereoWasapiOut,WasapiCaptureandWasapiLoopbackCaptureare[Obsolete]in favour ofWasapiPlayer/WasapiRecorder(the legacy types still ship and work);WasapiOut's embedded exclusive-mode resampler was removed, though it now adapts bit depth and channels, so only a sample-rate mismatch requires upstream resampling- The low-level
IMMNotificationClientinterface andMMDeviceEnumerator.RegisterEndpointNotificationCallback/UnregisterEndpointNotificationCallbackare now internal — useCreateNotificationClient()and its events. The raw Core Audio and Media Foundation COM interfaces are likewise internal, andPropertyStoreProperty.Valueis nowobjectrather thanPropVariant - Some types moved package or namespace as part of the split — classic Windows MIDI I/O and
winmmtypes toNAudio.WinMM; the DMO/DirectSound types into the newNAudio.Dmopackage; plus smaller moves (AudioVolumeLevel,CaptureState,DmoMp3FrameDecompressor). Meta-package consumers are unaffected - Removed seven members that were already
[Obsolete]throughout NAudio 2, each with a direct replacement on the same class:WaveFileWriter.WriteData(both overloads →Write/WriteSamples),WaveFileReader.TryReadFloat(→ReadNextSampleFrame, which doesn't drop channels on stereo),AcmStream.Convert(int)(→ the overload returningsourceBytesConverted),WaveFormatConversionStream.SourceToDest/DestToSource(unreliable estimates with no replacement — usePosition/Length), andAsioAudioAvailableEventArgs.GetAsInterleavedSamples()(→ the overload taking a reusable array, avoiding an allocation per ASIO callback).AsioOut.Volumeis kept despite its obsolete notice — it's anIWavePlayerinterface member AudioMediaSubtypesmoved from theNAudio.Dmonamespace toNAudio.Wave. It ships inNAudio.Core, so cross-platform code previously neededusing NAudio.Dmo;to name the media subtype GUIDs even on Linux without the DMO package; it now sits alongsideWaveFormatExtensibleSimpleCompressorStream,ImpulseResponseConvolutionandNAudio.Extras.Equalizerwere removed — superseded byNAudio.Effects(CompressorEffect,ConvolutionReverbEffect,Equalizer)CueWaveFileReader,CueWaveFileWriter,BwfWriterandBextChunkInfowere removed, along withWaveFileReader.ExtraChunks/GetChunkData— the unified chunk model onWaveFileReader.ChunksandWaveFileWriterreplaces themMixingWaveProvider32was removed — it was an untested float-only mixer that offered nothing overMixingSampleProvider.ImaAdpcmWaveFormatwas removed — it was a non-functional stub used nowhereWaveFileWriter/AiffFileWriterno longer dispose a caller-supplied stream, matching the readers' ownership rule; only the filename constructor owns and closes the file.IgnoreDisposeStreamis no longer needed when writing to a stream you want to keep (#1040)- Finalizers were removed from
MediaFoundationTransform,MediaFoundationEncoderandMediaBuffer, andMediaTypeis nowIDisposable— callDispose() - Core Audio, Media Foundation and DMO errors now throw
CoreAudioException/MediaFoundationException, both subclasses ofCOMException, so existingcatch (COMException)keeps working
Notable bug fixes
The sampler, effects and WASAPI subsystems also saw extensive correctness work during
development. The full per-PR list is on the GitHub Release; the fixes most likely to
affect existing NAudio 2 code are:
WaveFileWriter.WriteSample/WriteSamples: fixed 32-bitWaveFormatExtensibleoutput writing near-silence or corrupt data — both paths ignored the declared SubFormat (#651)ToSampleProvider()now handlesWAVE_FORMAT_EXTENSIBLEPCM and IEEE float sources (e.g. multichannel or >16-bit WAV) instead of throwingUnsupported source encoding(#639);AudioFileReaderno longer routes such WAVs through an unnecessary ACM conversion streamWaveFileReader/AiffFileReader: malformed headers declaringBlockAlign=0throwInvalidDataExceptionfrom the constructor rather thanDivideByZeroExceptionlater (#1254); an oversizeddatachunk length is clamped to the bytes actually present (#1090); an oversizedfmtcbSizeno longer throws (#482)AiffFileReader/AiffFileWriter: 8-bit PCM is now read and written as signed two's-complement per the AIFF spec, fixing DC-shifted/garbled playback (#1178)BlockAlignReductionStream.Read: a read larger than the 4-second internal buffer no longer silently truncates the stream — e.g. converting a non-PCM WAV viaAudioFileReader(#1022)WaveOut: fixed a race where stopping or disposing faster than the buffer latency could throw aNullReferenceExceptionviaPlaybackStopped(#804);DirectSoundOut: fixed a startup race that could collapse playback immediately (#759)WasapiRecorder,WasapiCaptureandWasapiLoopbackCapture: a capture device removed mid-recording no longer crashes the process —RecordingStoppedalways fires with the originating exception (#672). Silent packets no longer leak the uninitialised WASAPI buffer as a burst of stale audio- Fixed an access violation that could crash the process when an endpoint notification fired after
RegisterEndpointNotificationCallback— Windows does not AddRef the client, so the CCW was being collected (#1394) AudioClient.Disposeis now idempotent and safe against concurrent disposal (#1183);MMDevice.Disposereleases the property store deterministically (#1145);AudioSessionControlsupports multiple event clients without leaking (#1263);AudioEndpointVolume.OnVolumeNotificationreports the correct channel (#351)AcmInterop: serialised allmsacm32P/Invokes process-wide, fixing process-killing access violations under concurrent ACM useResamplerDmoStream: fixed an infinite loop onReadafter seeking and the loss of the resampler tail at end-of-stream (#607, #608);LoopStream.Readno longer spins at 100% CPU when the source can't satisfy a read (#1338)FastFourierTransform.FFT: fixed drifting high-frequency bins at large FFT sizes by carrying the twiddle-factor recurrence in double precision (#520)WdlResampler: backported upstream Cockos WDL fixes, including reinterleaving on channel-count change and denormal flushing in the IIR feedback path (#800)WaveViewer: fixed rendering upside-down (#801, #818) and now renders any source format viaToSampleProvider()(#564)Mp3FileReader: fixed false sample-rate-change errors near end of file, and more robust frame parsing against album art and trailing metadata;MidiFilepreserves running status across meta eventsWaveFormat.Serialize: PCM formats now write the canonical 16-bytefmtchunk (#934, #1098)- Hardened Media Foundation and DMO interop against COM ref leaks on error paths (#1293)
Demos and tooling
NAudioDemoandNAudioWpfDemowere substantially reworked against the new APIs, including a rebuilt WASAPI Recorder panel driven byWasapiRecorderBuilder, transport/volume/position controls across the playback panels, and a Graphic EQ panel onNAudio.Effects- The network chat demo is now UDP-only with a bounded jitter buffer and Opus codecs (via
Concentus, replacing the vendored NSpeex binary), and gained a tutorial - The documentation site (tutorials plus a generated API reference) is published to GitHub Pages from
Docs/and the source XML comments. Every package'sprojectUrland README now point at it; nuget.org still links the GitHub repo via the package'srepositorymetadata