Skip to content

Bump the nuget group with 2 updates - #33

Merged
tobymarks merged 4 commits into
mainfrom
dependabot/nuget/windows/src/Inlaut.App/nuget-c59eef05e7
Oct 23, 2026
Merged

tobymarks merged 4 commits into
mainfrom
dependabot/nuget/windows/src/Inlaut.App/nuget-c59eef05e7

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Oct 20, 2026

Copy link
Copy Markdown
Contributor

Updated NAudio from 2.2.1 to 3.3.0.

Release notes

Sourced from NAudio's releases.

3.3.0

A packaging and nullability release. The NAudio meta-package is now a single
net9.0 package that brings the Windows backends (WinMM and WASAPI) to plain
netX.0 projects, so a net10.0 console app on Windows gets working MP3
decoding and playback rather than a cross-platform subset that threw
NotSupportedException. In exchange it no longer pulls in NAudio.Asio,
NAudio.Dmo or NAudio.WinForms, which must now be referenced directly if
used. NAudio.WinMM, NAudio.Asio, NAudio.Dmo and NAudio.Vst3 likewise
now target plain net9.0.

Every NAudio package is now compiled with nullable reference types enabled.
This is a source-level change with no binary breaks, but projects with
nullable enabled may see new warnings, and a number of members that used to
throw NullReferenceException now throw ObjectDisposedException or
InvalidOperationException instead.

The fixes centre on WasapiRecorder/WasapiCapture restarting cleanly after
both successful and failed starts, buffer and handle lifetime bugs in the
winmm MIDI backend, and frame-aligned seeking in MediaFoundationReader.

  • Breaking: the NAudio meta-package is now a single net9.0 package that pulls in NAudio.Core, NAudio.Midi, NAudio.WinMM and NAudio.Wasapi on every target framework. A plain netX.0 project on Windows (e.g. a console app on net10.0) now gets Mp3FileReader, WaveOut, WasapiPlayer and an AudioFileReader that reads MP3, where previously it silently got a cross-platform subset that threw NotSupportedException (#​1472). It no longer includes NAudio.Asio, NAudio.Dmo or NAudio.WinForms: add those packages if you use AsioOut/AsioDevice, DirectSoundOut or the DMO effects, or WaveOutWindow/WaveInWindow/the NAudio.Gui controls. AudioFileReader now chooses its Media Foundation/ACM paths at runtime, and off Windows its NotSupportedException messages point to NAudio.SoundFile. NAudio.Extras is now single-target net9.0, with AudioPlaybackEngine marked Windows-only (#​1485)
  • NAudio.WinMM, NAudio.Asio, NAudio.Dmo and NAudio.Vst3 now target plain net9.0 instead of net9.0-windows, matching NAudio.Wasapi. They remain Windows-only, enforced by [SupportedOSPlatform("windows")], but can now be referenced directly from a plain netX.0 project (calls show CA1416 warnings unless guarded or the project is marked Windows-only) and built on Linux/macOS without EnableWindowsTargeting. No change for projects targeting netX.0-windows (#​1482)
  • Nullable reference types in NAudio.Core - NAudio.Core is now compiled with nullable reference types enabled, so its public API carries nullability annotations (e.g. WaveFileReader.ReadNextSampleFrame and Mp3Frame.LoadFromStream return nullable types, and Mp3Frame.RawData is byte[]? when a frame is read without its data). This is a source-level change only: there are no binary breaks, but projects with nullable enabled may see new warnings, and overrides of NAudio.Core virtual members may need matching annotations. XingHeader.LoadXingHeader now returns null for a frame read without its data instead of throwing. Thanks to @​Seb-stian (#​1452)
  • Nullable reference types in NAudio.Midi - NAudio.Midi is now also compiled with nullable reference types enabled (e.g. MidiInMessageEventArgs.MidiEvent and NoteOnEvent.OffEvent are nullable). Source-level change only; projects with nullable enabled may see new warnings. MidiEvent.ReadNextEvent now throws FormatException instead of NullReferenceException for running status with no previous event, and RawMetaEvent treats null data as empty (#​825)
  • Nullable reference types in NAudio.WinMM - NAudio.WinMM is now compiled with nullable reference types enabled (e.g. AcmDriver.FindByShortName and WaveCapabilitiesHelpers.GetNameFromGuid return nullable types, and AcmDriver.ShowFormatChooseDialog has nullable out parameters). Source-level change only; projects with nullable enabled may see new warnings. WaveOut.OutputWaveFormat before Init now throws InvalidOperationException, AcmStream members throw ObjectDisposedException after dispose, and GetNameFromGuid returns null instead of throwing when the registry key is missing, where each previously threw NullReferenceException (#​825)
  • Nullable reference types in NAudio.SoundFile and NAudio.Sampler - both packages are now compiled with nullable reference types enabled (e.g. the SoundFileTags fields, SoundFileWriterOptions.Tags and SoundFileException.Function are nullable, and the TryLoad methods on WaveSampleLoader / ISfzSampleLoader mark left as non-null on success and right as null for mono). Source-level change only; projects with nullable enabled may see new warnings, and custom ISfzSampleLoader implementations may need matching annotations (#​825)
  • Nullable reference types in NAudio.WinForms, NAudio.Alsa and NAudio.Extras - these packages are now compiled with nullable reference types enabled (e.g. WaveViewer.WaveStream, AlsaException.Function and the control/device events are nullable). Source-level change only; projects with nullable enabled may see new warnings. AlsaOut.OutputWaveFormat and WaveOutWindow.OutputWaveFormat now throw InvalidOperationException before Init (previously null and NullReferenceException respectively), and WaveOutWindow.Play before Init throws InvalidOperationException instead of NullReferenceException (#​825)
  • Nullable reference types in NAudio.Asio - NAudio.Asio is now compiled with nullable reference types enabled (e.g. the optional AsioPlaybackOptions.OutputChannels / AsioDuplexOptions.InputChannels, the AsioDevice/AsioOut events and the AsioDriverExt callbacks are nullable; required option members such as Source and Processor stay non-nullable). Source-level change only; projects with nullable enabled may see new warnings. AsioOut members now throw ObjectDisposedException after Dispose and AsioOut.OutputWaveFormat throws InvalidOperationException when no playback source is initialised, where they previously threw NullReferenceException or returned null (#​825)
  • Nullable reference types in NAudio.Dmo - NAudio.Dmo is now compiled with nullable reference types enabled (e.g. DirectSoundOut.PlaybackStopped and DirectSoundDeviceInfo.ModuleName are nullable). Source-level change only; projects with nullable enabled may see new warnings. DirectSoundOut.OutputWaveFormat now throws InvalidOperationException before Init instead of returning null, and the MediaObject wrappers, DmoResampler.MediaObject, WindowsMediaMp3Decoder.MediaObject and DmoOutputDataBuffer.MediaBuffer throw ObjectDisposedException after Dispose instead of returning null or throwing NullReferenceException (#​825)
  • Nullable reference types in NAudio.Wasapi (CoreAudioApi and MediaFoundation) - the NAudio.CoreAudioApi and NAudio.MediaFoundation types are now annotated for nullable reference types (e.g. AudioClient.TryGetAcousticEchoCancellationControl, MMDeviceEnumerator.TryGetDefaultAudioEndpoint, MfSourceReader.ReadSample, PropertyStoreProperty.Value and Part.AudioVolumeLevel/AudioMute/JackDescription are nullable); WasapiOut, WasapiCapture and the other top-level classes follow in a separate change. Source-level change only; projects with nullable enabled may see new warnings. The CoreAudio and Media Foundation COM wrappers now throw ObjectDisposedException when used after Dispose instead of NullReferenceException, AudioSessionManager.Sessions throws InvalidOperationException instead of returning null when sessions are unavailable, and AudioSessionControl.AudioMeterInformation / SimpleAudioVolume throw NotSupportedException instead of returning null if the session does not expose those interfaces (#​825)
  • Nullable reference types in NAudio.Wasapi (playback, capture and Media Foundation classes) - WasapiOut, WasapiCapture, WasapiPlayer, WasapiRecorder, their builders and MediaFoundationReader/StreamMediaFoundationReader/MediaFoundationEncoder are now annotated too, completing NAudio.Wasapi (e.g. WasapiPlayer/WasapiRecorder.DeviceId and DeviceFriendlyName, LowLatencyUnavailableReason, WasapiRecorder.AcousticEchoCancellationControl, WasapiPlayer.GetSupportedExclusiveFormat, MediaFoundationEncoder.SelectMediaType and the playback/recording events are nullable). Source-level change only; projects with nullable enabled may see new warnings. The WASAPI classes now throw ObjectDisposedException when used after Dispose, and report InvalidOperationException instead of NullReferenceException through PlaybackStopped when playback is started without Init (#​825)
  • Nullable reference types in NAudio.MacOS - NAudio.MacOS is now compiled with nullable reference types enabled (e.g. AudioSystemObject.DefaultInputDevice/DefaultOutputDevice, the ConvertUIDToDevice-style lookups, AudioObject.Owner, AudioDevice.Icon, ExtendedAudioFileReaderSettings.OutputFormat, ExtendedAudioFileWriterSettings.FileType/ProvidingFormat and the player, recorder and property-listener events are nullable). Source-level change only; projects with nullable enabled may see new warnings. Object-list properties such as AudioSystemObject.Devices now skip unknown object IDs instead of returning null entries, the parameterless CoreAudioPlayer/CoreAudioRecorder constructors throw InvalidOperationException instead of ArgumentNullException when there is no default device, and ExtendedAudioFileWriter captures ProvidingFormat when created rather than re-reading the settings object on every write (#​825)
  • Fixed WasapiRecorder and WasapiCapture failing with AUDCLNT_E_ALREADY_INITIALIZED when restarted after a start that failed late in initialization (e.g. no AEC reference control); the original error is now reported again (#​1493)
  • Fixed WasapiRecorder and WasapiCapture being left in the Starting state when initialization throws, so later StartRecording calls failed with "Already recording". (#​1490)
  • Fixed WasapiRecorder not able to re-start after successfully stopping the recorder. (#​1479)
  • Fixed several buffer and handle lifetime bugs in the winmm MIDI backend: MidiOut.SendBuffer no longer frees a sysex buffer while the driver may still own it, MidiIn now stops input before resetting it, and neither class calls into winmm with a handle it never opened. MidiOut.SendBuffer now blocks until the driver releases the buffer and throws MmException if the send fails (#​1478)
  • Fixed MediaFoundationReader reporting a Position that was not a whole number of frames after seeking a compressed file (e.g. MP3 or AAC), up to a frame before the requested position, and a Length that could include a partial frame. Seeks now round down to a frame boundary and land exactly on it (#​1488)

3.2.0

A feature and tidy-up release. Its headline is a first preview of macOS
support: the new NAudio.MacOS package wraps Core Audio for playback and
recording, Extended Audio File Services for reading and writing compressed
formats, and AudioConverter for resampling. It ships pre-release only while its
API settles, alongside the stable versions of the other packages. VB.NET users
also get base classes and a guide that keep the NAudio 2 array-based Read
signature.

Several legacy APIs that have modern replacements are now [Obsolete], to be
removed in the next major version. The
fixes include DirectSoundOut, which failed every playback in 3.1.0, and
WasapiPlayer/WasapiOut getting stuck in the Playing state after a source
error.

  • macOS support (preview) - A new wrappers library is added wrapping macOS native API's for playback/recording, reading/writing files and resampling audio. The NAudio.MacOS package ships pre-release only (X.Y.Z-preview.N) while its API settles, so it stays pre-release alongside stable releases of the other packages. Special thanks to @​mdcdi1315 (#​1325) for the work and the tests. For more information, see the design doc that describes the decisions that helped shape the wrappers. (#​1398)
  • VB.NET support - Added SampleProviderBase and WaveProviderBase, base classes that keep the NAudio 2 Read(buffer, offset, count) signature for languages that cannot name a Span<T> in a method signature, and a Using NAudio from VB.NET guide covering playback, recording and custom providers from VB (#​1426)
  • Deprecated legacy APIs that have modern replacements: Wave16ToFloatProvider, WaveFloatTo16Provider and Wave32To16Stream (use ToSampleProvider() / ToWaveProvider16()), IgnoreDisposeStream (no longer needed), ByteArrayExtensions (use the BCL), MidiMessage (use the typed MIDI events), ResamplerDmoStream/DmoResampler (use MediaFoundationResampler or WdlResamplingSampleProvider), DmoEffectWaveProvider and the Dmo* effects (use NAudio.Effects), AsioOut's recording path (use AsioDevice), WaveFilter, and ProgressLog. Added AsioOut.IsSupported() and deprecated the lowercase isSupported() (#​1466)
  • Deprecated WaveFileReader.ReadNextSampleFrame in favour of ToSampleProvider(), which supports more formats and doesn't allocate an array per sample frame (#​1465)
  • Reduced allocations when reading and writing WAV files, added ReadOnlySpan<byte> overloads of WaveFileWriter.AddChunk and ChunkIdentifier.ChunkIdentifierToInt32, and fixed WaveChunks.GetData leaving the stream position changed when a read fails. ChunkIdentifierToInt32 now throws ArgumentOutOfRangeException for identifiers that aren't four bytes (#​1457)
  • Fixed DirectSoundOut failing every playback with DirectSoundException 0x80004001 (or an ArgumentException for a format with extra data, e.g. one read from a WAV by WaveFileReader): the secondary buffer's WAVEFORMATEX was still a GCHandle-pinned WaveFormat instance — a site missed in the #​1432 marshalling conversion, since WaveFormat no longer carries [StructLayout] — and now marshals via WaveFormat.MarshalToPtr (#​1456)
  • Fixed WasapiPlayer and WasapiOut being stranded in the Playing state, unable to play again, when the source's Read threw or the source ended before the first buffer was filled (#​1442)
  • Fixed WaveFileWriter.WriteSample and WriteSamples(short[]) throwing for plain (non-extensible) 32-bit integer PCM formats (#​1463)
  • WaveFileReader.ReadNextSampleFrame now throws InvalidDataException for a WAV header with an invalid channel count or bit depth (#​1464)
  • Changed the WaveStream.CurrentTime setter to clamp to the bounds of the stream, and corrected the XML documentation for the core audio interfaces (#​1441)
  • Reworked the macOS CoreAudioPlayer and CoreAudioRecorder non-interleaved path, used for devices that expose one mono stream per channel; the recorder now also drains buffered audio when stopped, and non-interleaved streams carrying more than one channel are rejected explicitly (preview) (#​1461)
  • ExtendedAudioFileServicesReader.CurrentTime and TotalTime on macOS now throw ObjectDisposedException after the reader is disposed, rather than a native exception (preview) (#​1451)
  • Refreshed the NuGet package icon, now rendered from the new SVG version of the NAudio logo as a sharper, square 256×256 PNG (#​1467)
  • Fixed the Help and About links in the AudioFileInspector, MidiFileConverter and MixDiff sample apps, which threw on .NET 9 instead of opening the help page or browser, and pointed the links and help pages at GitHub rather than CodePlex (#​1469)

3.1.0

A correctness release, with Native AOT as the theme. NAudio's remaining
[StructLayout] interop types — WAVEHDR, ACMSTREAMHEADER and WaveFormat
itself — were passed to native code by value, which CoreCLR pins in place but
the AOT marshaller copies into a per-call temporary. Anything the driver or
codec wrote back was silently discarded, so WaveIn/WaveOut, ACM conversion
(and with it Mp3FileReader and AudioFileReader) and every WASAPI, Media
Foundation and DMO format negotiation were broken in an AOT-published app while
building and running cleanly. Those paths now marshal by hand into stable
unmanaged blocks, and NAudio.WinMM joins the AOT-compatible package set.

The two breaking changes below both fall out of that work. Also fixed are two
3.0.0 regressions — Mp3FileReaderBase seeking on files with a Xing/Info
header, and WdlResamplingSampleProvider losing samples when its source
under-feeds — and a pair of infinite loops in the WAV parser on corrupt files.

  • Breaking: WaveFormat and its subclasses no longer carry [StructLayout], so Marshal.SizeOf and Marshal.PtrToStructure on them now throw ArgumentException instead of silently returning wrong data under Native AOT (Marshal.SizeOf<WaveFormatExtensible>() returned 22 rather than 40, and a decoded format kept its constructor defaults). NAudio itself stopped marshalling these types in 3.1.0; use ToWaveFormatExBytes, MarshalToPtr or MarshalFromPtr to cross a native boundary (#​1432)
  • Breaking: AudioClient.IsFormatSupported and WasapiPlayer.IsFormatSupported now return the closest-match format as out WaveFormat rather than out WaveFormatExtensible. WASAPI documents this format as either a WAVEFORMATEX or a WAVEFORMATEXTENSIBLE, and the old signature could only represent the latter — a plain format was previously decoded as a WaveFormatExtensible whose base fields were valid but whose extensible fields were meaningless. Callers needing the extensible fields should pattern-match (#​1425)
  • Fixed WaveIn/WaveOut failing under Native AOT with WaveHeaderUnprepared ("The wave header was not prepared"). The WAVEHDR was a [StructLayout] class passed to winmm by value, which CoreCLR pins in place but NativeAOT copies into a per-call temporary, so the driver's WHDR_PREPARED/WHDR_DONE/dwBytesRecorded writes were discarded. It is now a struct in a stable unmanaged block (#​1425)
  • Fixed ACM conversion failing under Native AOT — WaveFormatConversionStream, AcmStream and so Mp3FileReader and AudioFileReader. ACMSTREAMHEADER was a [StructLayout] class passed to msacm32 by value, and the codec keeps private state in the header's reserved fields between acmStreamPrepareHeader, acmStreamConvert and acmStreamUnprepareHeader; the AOT marshaller's per-call copy round-trips only the declared fields, so that state was lost and conversion failed. It is now a struct in a stable unmanaged block, as WAVEHDR already is (#​1425)
  • Fixed WaveFormat.MarshalToPtr and WaveFormat.MarshalFromPtr corrupting any WaveFormat subclass under Native AOT — the AOT marshaller drops the inherited WAVEFORMATEX fields of a class hierarchy, so a WaveFormatExtensible was written with its SubFormat GUID over the sample rate. Every remaining site that sized or wrote a WaveFormat with Marshal.SizeOf/StructureToPtr was converted too: WASAPI (AudioClient), Media Foundation (MFInitMediaTypeFromWaveFormatEx, reachable from MediaFoundationResampler/MediaFoundationEncoder), DMO (DmoMediaType.SetWaveFormat, MediaObject) and ACM (AcmStream, AcmDriver) (#​1425)
  • WaveFormat.MarshalToPtr now always allocates at least the 18 + cbSize bytes it advertises. A WaveFormat subclass that declares extraSize but doesn't write it in Serialize previously produced a block shorter than its own cbSize, which a native consumer would read past (#​1425)
  • Added WaveFormat.ToWaveFormatExBytes(), which renders a WaveFormat as a native WAVEFORMATEX byte array. MarshalToPtr is now a thin wrapper over it, for callers who need an unmanaged block rather than a buffer they already own (#​1425)
  • Added a Serialize override to Mp3WaveFormat, which previously advertised cbSize = 12 but wrote none of its 12 MPEGLAYER3WAVEFORMAT extra bytes (#​1425)
  • WaveFormatExtraData now sizes its buffer from cbSize instead of holding a fixed 100-byte array, so a fmt chunk declaring more than 100 bytes of extra data keeps it rather than having all of it discarded (#​482). The fixed size existed only because [MarshalAs(ByValArray, SizeConst = 100)] needed a compile-time length. ExtraData is now exactly ExtraSize bytes long rather than always 100 (#​1432)
  • NAudio.WinMM is now marked IsAotCompatible, and the AOT smoke test covers the winmm WAVEHDR/WAVEFORMATEX paths (#​1425)
  • Fixed Mp3FileReaderBase seeking silently restarting playback from the beginning of the file on MP3s with a Xing/Info header — the lazy frame index was gated on IsLengthExact, which such a header sets without any frame having been scanned. Also fixed seeks landing on the wrong frame when the target fell exactly on a frame boundary, and Xing/Info header frames being indexed as audio (shifting every seek in those files ~26 ms early). A 3.0.0 regression (#​1419)
  • Fixed WdlResamplingSampleProvider losing samples, and eventually returning 0 permanently, when asked for more output than the source could supply — a 3.0.0 regression that broke the common pattern of reading generously from a BufferedWaveProvider-backed capture chain. WdlResampler.ResampleOut also no longer drifts in input-driven (feed) mode when handed fewer samples than ResamplePrepare requested (#​1412)
  • Fixed two infinite loops in the WAV parser triggered by corrupt files declaring a negative chunk size. An RF64 ds64 chunk with a negative dataChunkLength, or a LIST/adtl sub-chunk with a negative size, made the chunk walk advance by zero bytes per iteration and spin at 100% CPU without throwing. Negative and oversized sizes are now rejected where they are read, and an undersized ds64 chunk throws FormatException rather than ArgumentOutOfRangeException (#​1428)
  • Fixed the NAudioConsoleTest WASAPI exclusive-mode quick scan reporting no supported formats at all on devices that support plenty — it built its probe formats with an empty WAVEFORMATEXTENSIBLE channel mask, which drivers such as Realtek reject outright. It now probes with the canonical layout for the channel count, the same mask the library's own format adaptation uses (#​1431)

3.0.1

A patch release. The headline fix is packaging: the NAudio and NAudio.Extras
meta-packages now ship a plain net9.0-windows leg, so WinForms and WPF projects
targeting netX.0-windows get the full Windows stack again.

  • Breaking: AudioFileReader now throws NotSupportedException instead of InvalidOperationException when the cross-platform build is asked for a format it cannot read, and the messages simply state that rather than suggesting an NAudio.Wasapi install that could never have helped (#​1407)
  • Fixed the NAudio and NAudio.Extras meta-packages resolving their portable net9.0 asset on projects targeting a plain netX.0-windows TFM (the WinForms/WPF template default), which silently dropped the entire Windows stack — no WaveOut, WASAPI, Media Foundation, ASIO, DMO or WinForms types, and AudioFileReader throwing "MP3 file reading requires the NAudio.Wasapi package". Both packages now also ship a plain net9.0-windows leg (#​1407)
  • Projects on a plain netX.0-windows TFM may now see CA1416 warnings when calling WASAPI process-loopback capture. The warning is correct — those callers do need an OperatingSystem.IsWindowsVersionAtLeast(10, 0, 19041) guard — and was previously hidden because the only Windows asset available already implied that floor (#​1407)
  • Sample and tool apps now roll forward onto newer .NET runtimes, so running them no longer requires the .NET 9 runtime to be installed (#​1408)
  • Fixed AiffFileReader reporting too long a Length and throwing IndexOutOfRangeException when the SSND chunk declares a non-zero offset (#​1405)
  • Fixed AiffFileReader.Read throwing IndexOutOfRangeException when the source stream returns fewer bytes than requested (#​1405)

3.0.0

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
  • NAudio is now a set of focused packages: NAudio.Core, NAudio.Midi, NAudio.WinMM, NAudio.Wasapi, NAudio.Asio, NAudio.Dmo, NAudio.WinForms, plus the new NAudio.Effects (shipped in NAudio.Core), NAudio.Sampler, NAudio.Vst3, NAudio.Alsa and NAudio.SoundFile. The NAudio meta-package still pulls the Windows stack together, so existing consumers see no change. See Docs/Architecture/NAudio3AssemblyLayoutPlan.md
  • NAudio.Core, NAudio.Midi, NAudio.Wasapi, NAudio.Dmo, NAudio.Sampler, NAudio.SoundFile and NAudio.Alsa are Native-AOT compatible (IsAotCompatible=true), enforced in CI by NAudioAotSmokeTest
  • NAudio.Wasapi targets plain net9.0 (Windows-only at runtime via [SupportedOSPlatform("windows")]), so cross-platform apps can reference it and build on Linux/macOS without EnableWindowsTargeting. The WinRT MIDI backend moved to NAudio.Midi, which now dual-targets net9.0;net9.0-windows10.0.19041.0 (#​1384)
  • The NAudio.Uap package is removed — use WasapiPlayerBuilder / WasapiRecorderBuilder
  • Packages ship with SourceLink, .snupkg symbol 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.Effects framework: IAudioEffect / EffectSampleProvider / EffectChain with 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 via WasapiPlayerBuilder / WasapiRecorderBuilder: IAudioClient3 low 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 AsioDevice replacing AsioOut: explicit playback/recording/duplex modes, non-contiguous channels, per-channel Span<float> callbacks, driver-reset recovery and per-buffer timing. AsioOut is preserved as a facade. See Docs/AsioMigration.md
  • Cross-platform audio files — new NAudio.SoundFile package: 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.Alsa package: AlsaOut (IWavePlayer) and AlsaIn (IWaveIn) plus AlsaDeviceEnumerator, backed by libasound. See Docs/PlayAudioFileLinuxAlsa.md and Docs/RecordAudioFileLinuxAlsa.md (#​1182)
  • VST 3 hosting — new NAudio.Vst3 package (Windows-only): discover, load and host VST 3 effects and instruments, with parameters, state and .vstpreset presets, native editor windows, program lists/units, latency compensation, and live/offline MIDI-file playback through the shared MIDI pipeline. See the NAudio.Vst3 README and Docs/Architecture/Vst3Hosting.md. VST is a registered trademark of Steinberg Media Technologies GmbH
  • Software sampler — new NAudio.Sampler package: polyphonic, cross-platform playback of SoundFont (.sf2) and SFZ instruments and single-sample instruments, rendered as an ISampleProvider (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 an MMDeviceNotificationClient exposing DeviceStateChanged, DeviceAdded, DeviceRemoved, DefaultDeviceChanged and PropertyValueChanged as 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 WinRT WinRTMidiIn / WinRTMidiOut and backend-agnostic IMidiInput / IMidiOutput; and a new IMidiInstrument seam (MidiFileSequence / SequencedMidiPlayer / OfflineMidiRenderer / LiveMidiInstrument) giving an end-to-end MIDI-file → audio pipeline that drives the sampler or a hosted VST 3 instrument. MidiFile also reads RIFF-RMID (.rmi) files (#​1236) and MidiFile.Export gains a Stream overload, thanks to @​MaKiPL (#​499)
  • Sequencing — a portable NAudio.Sequencing namespace in NAudio.Core (tempo and time-signature maps, transport, EventTimeline, swing, and a sample-accurate per-buffer dispatcher) underpinning MIDI-file playback and the sampler. See Docs/Architecture/Sequencing.md
  • Live capture mixing — new NAudio.Extras helpers CaptureMixerInput and RealtimeCaptureMixer capture 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 — AudioFileReader and CachedSound gain Stream constructors, 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). StreamMediaFoundationReader also gains optional contentType / originName hints and Ogg container sniffing (#​952)
  • WAV chunk model — WaveFileReader.Chunks with an IWaveChunkInterpreter<T> extension point and built-in interpreters for cue lists, BWF bext (BroadcastExtension, now read and write, with v2 loudness) and LIST/INFO (InfoMetadata); WaveFileWriter gains AddCue, WriteCueList, WriteBroadcastExtension, arbitrary AddChunk and RF64 promotion via WaveFileWriterOptions (#​1013)
  • Latency reporting — new IWaveLatency interface in NAudio.Core exposing AverageLatency / CurrentLatency for A/V sync and drift detection, implemented across the playback and capture classes (#​601)
  • Sample providers and DSP — new ChannelMixerSampleProvider with ready-made ChannelMixMatrix routings, thanks to @​antiduh (#​982); a new FftProcessor; Span<T> overloads across the codec/DSP surface; reusable building blocks (EnvelopeFollower, DelayLine, Lfo, Oversampler, LinkwitzRileyCrossover, PartitionedConvolver, …); plus improvements to SmbPitchShiftingSampleProvider (#​922), AdsrSampleProvider (#​671) and FadeInOutSampleProvider (#​1136)
  • WaveFormatExtensible — new constructors for SubFormat, valid-bits-per-sample and channel mask, readable ValidBitsPerSample / ChannelMask, and a [Flags] Speakers enum for building channel masks (#​1325)
  • WASAPI sessions and devices — AudioSessionControl.SetDuckingPreference(bool) (#​760); WasapiPlayer / WasapiRecorder expose DeviceId and DeviceFriendlyName for 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.Read now take a single Span<byte> / Span<float> (was buffer/offset/count) — callers migrate via source.Read(buffer.AsSpan(offset, count)); implementations override the span method
    ... (truncated)

2.4.0

  • Added DeviceCount and GetCapabilities static methods to WaveOutEvent so output
    devices can be enumerated without referencing NAudio.WinForms (#​1331, #​777)
  • Fixed WASAPI and Media Foundation interop under Unity's Mono runtime, which marshalled
    formatted class parameters as COM interfaces; they are now explicitly marked
    [MarshalAs(UnmanagedType.LPStruct)] (#​1414)

2.3.0

  • Performance improvements for PropertyStore and Core Audio property access (#​1206)
  • Improved multi-channel playback compatibility in WASAPI exclusive mode (#​1234)
  • Fixed a bug that prevented WasapiCapture from using exclusive mode (#​1122)
  • Fixed RF64 header parsing in WaveFileChunkReader.ReadWaveHeader (#​1231)
  • PropVariant now supports VT_EMPTY by returning null (#​1071)
  • Better exception when calling disposed AcmStream.Convert (#​1108)
  • Fixed AcmStreamHeader finalizer crash with corrupted data (#​1199)
  • Added net6.0 targets for NAudio.Asio and NAudio.WinMM to remove registry dependency (#​1139)
  • Updating TFMs, modernizing the UAP project to WinUI

Commits viewable in compare view.

Updated NAudio.Wasapi from 2.2.1 to 3.3.0.

Release notes

Sourced from NAudio.Wasapi's releases.

3.3.0

A packaging and nullability release. The NAudio meta-package is now a single
net9.0 package that brings the Windows backends (WinMM and WASAPI) to plain
netX.0 projects, so a net10.0 console app on Windows gets working MP3
decoding and playback rather than a cross-platform subset that threw
NotSupportedException. In exchange it no longer pulls in NAudio.Asio,
NAudio.Dmo or NAudio.WinForms, which must now be referenced directly if
used. NAudio.WinMM, NAudio.Asio, NAudio.Dmo and NAudio.Vst3 likewise
now target plain net9.0.

Every NAudio package is now compiled with nullable reference types enabled.
This is a source-level change with no binary breaks, but projects with
nullable enabled may see new warnings, and a number of members that used to
throw NullReferenceException now throw ObjectDisposedException or
InvalidOperationException instead.

The fixes centre on WasapiRecorder/WasapiCapture restarting cleanly after
both successful and failed starts, buffer and handle lifetime bugs in the
winmm MIDI backend, and frame-aligned seeking in MediaFoundationReader.

  • Breaking: the NAudio meta-package is now a single net9.0 package that pulls in NAudio.Core, NAudio.Midi, NAudio.WinMM and NAudio.Wasapi on every target framework. A plain netX.0 project on Windows (e.g. a console app on net10.0) now gets Mp3FileReader, WaveOut, WasapiPlayer and an AudioFileReader that reads MP3, where previously it silently got a cross-platform subset that threw NotSupportedException (#​1472). It no longer includes NAudio.Asio, NAudio.Dmo or NAudio.WinForms: add those packages if you use AsioOut/AsioDevice, DirectSoundOut or the DMO effects, or WaveOutWindow/WaveInWindow/the NAudio.Gui controls. AudioFileReader now chooses its Media Foundation/ACM paths at runtime, and off Windows its NotSupportedException messages point to NAudio.SoundFile. NAudio.Extras is now single-target net9.0, with AudioPlaybackEngine marked Windows-only (#​1485)
  • NAudio.WinMM, NAudio.Asio, NAudio.Dmo and NAudio.Vst3 now target plain net9.0 instead of net9.0-windows, matching NAudio.Wasapi. They remain Windows-only, enforced by [SupportedOSPlatform("windows")], but can now be referenced directly from a plain netX.0 project (calls show CA1416 warnings unless guarded or the project is marked Windows-only) and built on Linux/macOS without EnableWindowsTargeting. No change for projects targeting netX.0-windows (#​1482)
  • Nullable reference types in NAudio.Core - NAudio.Core is now compiled with nullable reference types enabled, so its public API carries nullability annotations (e.g. WaveFileReader.ReadNextSampleFrame and Mp3Frame.LoadFromStream return nullable types, and Mp3Frame.RawData is byte[]? when a frame is read without its data). This is a source-level change only: there are no binary breaks, but projects with nullable enabled may see new warnings, and overrides of NAudio.Core virtual members may need matching annotations. XingHeader.LoadXingHeader now returns null for a frame read without its data instead of throwing. Thanks to @​Seb-stian (#​1452)
  • Nullable reference types in NAudio.Midi - NAudio.Midi is now also compiled with nullable reference types enabled (e.g. MidiInMessageEventArgs.MidiEvent and NoteOnEvent.OffEvent are nullable). Source-level change only; projects with nullable enabled may see new warnings. MidiEvent.ReadNextEvent now throws FormatException instead of NullReferenceException for running status with no previous event, and RawMetaEvent treats null data as empty (#​825)
  • Nullable reference types in NAudio.WinMM - NAudio.WinMM is now compiled with nullable reference types enabled (e.g. AcmDriver.FindByShortName and WaveCapabilitiesHelpers.GetNameFromGuid return nullable types, and AcmDriver.ShowFormatChooseDialog has nullable out parameters). Source-level change only; projects with nullable enabled may see new warnings. WaveOut.OutputWaveFormat before Init now throws InvalidOperationException, AcmStream members throw ObjectDisposedException after dispose, and GetNameFromGuid returns null instead of throwing when the registry key is missing, where each previously threw NullReferenceException (#​825)
  • Nullable reference types in NAudio.SoundFile and NAudio.Sampler - both packages are now compiled with nullable reference types enabled (e.g. the SoundFileTags fields, SoundFileWriterOptions.Tags and SoundFileException.Function are nullable, and the TryLoad methods on WaveSampleLoader / ISfzSampleLoader mark left as non-null on success and right as null for mono). Source-level change only; projects with nullable enabled may see new warnings, and custom ISfzSampleLoader implementations may need matching annotations (#​825)
  • Nullable reference types in NAudio.WinForms, NAudio.Alsa and NAudio.Extras - these packages are now compiled with nullable reference types enabled (e.g. WaveViewer.WaveStream, AlsaException.Function and the control/device events are nullable). Source-level change only; projects with nullable enabled may see new warnings. AlsaOut.OutputWaveFormat and WaveOutWindow.OutputWaveFormat now throw InvalidOperationException before Init (previously null and NullReferenceException respectively), and WaveOutWindow.Play before Init throws InvalidOperationException instead of NullReferenceException (#​825)
  • Nullable reference types in NAudio.Asio - NAudio.Asio is now compiled with nullable reference types enabled (e.g. the optional AsioPlaybackOptions.OutputChannels / AsioDuplexOptions.InputChannels, the AsioDevice/AsioOut events and the AsioDriverExt callbacks are nullable; required option members such as Source and Processor stay non-nullable). Source-level change only; projects with nullable enabled may see new warnings. AsioOut members now throw ObjectDisposedException after Dispose and AsioOut.OutputWaveFormat throws InvalidOperationException when no playback source is initialised, where they previously threw NullReferenceException or returned null (#​825)
  • Nullable reference types in NAudio.Dmo - NAudio.Dmo is now compiled with nullable reference types enabled (e.g. DirectSoundOut.PlaybackStopped and DirectSoundDeviceInfo.ModuleName are nullable). Source-level change only; projects with nullable enabled may see new warnings. DirectSoundOut.OutputWaveFormat now throws InvalidOperationException before Init instead of returning null, and the MediaObject wrappers, DmoResampler.MediaObject, WindowsMediaMp3Decoder.MediaObject and DmoOutputDataBuffer.MediaBuffer throw ObjectDisposedException after Dispose instead of returning null or throwing NullReferenceException (#​825)
  • Nullable reference types in NAudio.Wasapi (CoreAudioApi and MediaFoundation) - the NAudio.CoreAudioApi and NAudio.MediaFoundation types are now annotated for nullable reference types (e.g. AudioClient.TryGetAcousticEchoCancellationControl, MMDeviceEnumerator.TryGetDefaultAudioEndpoint, MfSourceReader.ReadSample, PropertyStoreProperty.Value and Part.AudioVolumeLevel/AudioMute/JackDescription are nullable); WasapiOut, WasapiCapture and the other top-level classes follow in a separate change. Source-level change only; projects with nullable enabled may see new warnings. The CoreAudio and Media Foundation COM wrappers now throw ObjectDisposedException when used after Dispose instead of NullReferenceException, AudioSessionManager.Sessions throws InvalidOperationException instead of returning null when sessions are unavailable, and AudioSessionControl.AudioMeterInformation / SimpleAudioVolume throw NotSupportedException instead of returning null if the session does not expose those interfaces (#​825)
  • Nullable reference types in NAudio.Wasapi (playback, capture and Media Foundation classes) - WasapiOut, WasapiCapture, WasapiPlayer, WasapiRecorder, their builders and MediaFoundationReader/StreamMediaFoundationReader/MediaFoundationEncoder are now annotated too, completing NAudio.Wasapi (e.g. WasapiPlayer/WasapiRecorder.DeviceId and DeviceFriendlyName, LowLatencyUnavailableReason, WasapiRecorder.AcousticEchoCancellationControl, WasapiPlayer.GetSupportedExclusiveFormat, MediaFoundationEncoder.SelectMediaType and the playback/recording events are nullable). Source-level change only; projects with nullable enabled may see new warnings. The WASAPI classes now throw ObjectDisposedException when used after Dispose, and report InvalidOperationException instead of NullReferenceException through PlaybackStopped when playback is started without Init (#​825)
  • Nullable reference types in NAudio.MacOS - NAudio.MacOS is now compiled with nullable reference types enabled (e.g. AudioSystemObject.DefaultInputDevice/DefaultOutputDevice, the ConvertUIDToDevice-style lookups, AudioObject.Owner, AudioDevice.Icon, ExtendedAudioFileReaderSettings.OutputFormat, ExtendedAudioFileWriterSettings.FileType/ProvidingFormat and the player, recorder and property-listener events are nullable). Source-level change only; projects with nullable enabled may see new warnings. Object-list properties such as AudioSystemObject.Devices now skip unknown object IDs instead of returning null entries, the parameterless CoreAudioPlayer/CoreAudioRecorder constructors throw InvalidOperationException instead of ArgumentNullException when there is no default device, and ExtendedAudioFileWriter captures ProvidingFormat when created rather than re-reading the settings object on every write (#​825)
  • Fixed WasapiRecorder and WasapiCapture failing with AUDCLNT_E_ALREADY_INITIALIZED when restarted after a start that failed late in initialization (e.g. no AEC reference control); the original error is now reported again (#​1493)
  • Fixed WasapiRecorder and WasapiCapture being left in the Starting state when initialization throws, so later StartRecording calls failed with "Already recording". (#​1490)
  • Fixed WasapiRecorder not able to re-start after successfully stopping the recorder. (#​1479)
  • Fixed several buffer and handle lifetime bugs in the winmm MIDI backend: MidiOut.SendBuffer no longer frees a sysex buffer while the driver may still own it, MidiIn now stops input before resetting it, and neither class calls into winmm with a handle it never opened. MidiOut.SendBuffer now blocks until the driver releases the buffer and throws MmException if the send fails (#​1478)
  • Fixed MediaFoundationReader reporting a Position that was not a whole number of frames after seeking a compressed file (e.g. MP3 or AAC), up to a frame before the requested position, and a Length that could include a partial frame. Seeks now round down to a frame boundary and land exactly on it (#​1488)

3.2.0

A feature and tidy-up release. Its headline is a first preview of macOS
support: the new NAudio.MacOS package wraps Core Audio for playback and
recording, Extended Audio File Services for reading and writing compressed
formats, and AudioConverter for resampling. It ships pre-release only while its
API settles, alongside the stable versions of the other packages. VB.NET users
also get base classes and a guide that keep the NAudio 2 array-based Read
signature.

Several legacy APIs that have modern replacements are now [Obsolete], to be
removed in the next major version. The
fixes include DirectSoundOut, which failed every playback in 3.1.0, and
WasapiPlayer/WasapiOut getting stuck in the Playing state after a source
error.

  • macOS support (preview) - A new wrappers library is added wrapping macOS native API's for playback/recording, reading/writing files and resampling audio. The NAudio.MacOS package ships pre-release only (X.Y.Z-preview.N) while its API settles, so it stays pre-release alongside stable releases of the other packages. Special thanks to @​mdcdi1315 (#​1325) for the work and the tests. For more information, see the design doc that describes the decisions that helped shape the wrappers. (#​1398)
  • VB.NET support - Added SampleProviderBase and WaveProviderBase, base classes that keep the NAudio 2 Read(buffer, offset, count) signature for languages that cannot name a Span<T> in a method signature, and a Using NAudio from VB.NET guide covering playback, recording and custom providers from VB (#​1426)
  • Deprecated legacy APIs that have modern replacements: Wave16ToFloatProvider, WaveFloatTo16Provider and Wave32To16Stream (use ToSampleProvider() / ToWaveProvider16()), IgnoreDisposeStream (no longer needed), ByteArrayExtensions (use the BCL), MidiMessage (use the typed MIDI events), ResamplerDmoStream/DmoResampler (use MediaFoundationResampler or WdlResamplingSampleProvider), DmoEffectWaveProvider and the Dmo* effects (use NAudio.Effects), AsioOut's recording path (use AsioDevice), WaveFilter, and ProgressLog. Added AsioOut.IsSupported() and deprecated the lowercase isSupported() (#​1466)
  • Deprecated WaveFileReader.ReadNextSampleFrame in favour of ToSampleProvider(), which supports more formats and doesn't allocate an array per sample frame (#​1465)
  • Reduced allocations when reading and writing WAV files, added ReadOnlySpan<byte> overloads of WaveFileWriter.AddChunk and ChunkIdentifier.ChunkIdentifierToInt32, and fixed WaveChunks.GetData leaving the stream position changed when a read fails. ChunkIdentifierToInt32 now throws ArgumentOutOfRangeException for identifiers that aren't four bytes (#​1457)
  • Fixed DirectSoundOut failing every playback with DirectSoundException 0x80004001 (or an ArgumentException for a format with extra data, e.g. one read from a WAV by WaveFileReader): the secondary buffer's WAVEFORMATEX was still a GCHandle-pinned WaveFormat instance — a site missed in the #​1432 marshalling conversion, since WaveFormat no longer carries [StructLayout] — and now marshals via WaveFormat.MarshalToPtr (#​1456)
  • Fixed WasapiPlayer and WasapiOut being stranded in the Playing state, unable to play again, when the source's Read threw or the source ended before the first buffer was filled (#​1442)
  • Fixed WaveFileWriter.WriteSample and WriteSamples(short[]) throwing for plain (non-extensible) 32-bit integer PCM formats (#​1463)
  • WaveFileReader.ReadNextSampleFrame now throws InvalidDataException for a WAV header with an invalid channel count or bit depth (#​1464)
  • Changed the WaveStream.CurrentTime setter to clamp to the bounds of the stream, and corrected the XML documentation for the core audio interfaces (#​1441)
  • Reworked the macOS CoreAudioPlayer and CoreAudioRecorder non-interleaved path, used for devices that expose one mono stream per channel; the recorder now also drains buffered audio when stopped, and non-interleaved streams carrying more than one channel are rejected explicitly (preview) (#​1461)
  • ExtendedAudioFileServicesReader.CurrentTime and TotalTime on macOS now throw ObjectDisposedException after the reader is disposed, rather than a native exception (preview) (#​1451)
  • Refreshed the NuGet package icon, now rendered from the new SVG version of the NAudio logo as a sharper, square 256×256 PNG (#​1467)
  • Fixed the Help and About links in the AudioFileInspector, MidiFileConverter and MixDiff sample apps, which threw on .NET 9 instead of opening the help page or browser, and pointed the links and help pages at GitHub rather than CodePlex (#​1469)

3.1.0

A correctness release, with Native AOT as the theme. NAudio's remaining
[StructLayout] interop types — WAVEHDR, ACMSTREAMHEADER and WaveFormat
itself — were passed to native code by value, which CoreCLR pins in place but
the AOT marshaller copies into a per-call temporary. Anything the driver or
codec wrote back was silently discarded, so WaveIn/WaveOut, ACM conversion
(and with it Mp3FileReader and AudioFileReader) and every WASAPI, Media
Foundation and DMO format negotiation were broken in an AOT-published app while
building and running cleanly. Those paths now marshal by hand into stable
unmanaged blocks, and NAudio.WinMM joins the AOT-compatible package set.

The two breaking changes below both fall out of that work. Also fixed are two
3.0.0 regressions — Mp3FileReaderBase seeking on files with a Xing/Info
header, and WdlResamplingSampleProvider losing samples when its source
under-feeds — and a pair of infinite loops in the WAV parser on corrupt files.

  • Breaking: WaveFormat and its subclasses no longer carry [StructLayout], so Marshal.SizeOf and Marshal.PtrToStructure on them now throw ArgumentException instead of silently returning wrong data under Native AOT (Marshal.SizeOf<WaveFormatExtensible>() returned 22 rather than 40, and a decoded format kept its constructor defaults). NAudio itself stopped marshalling these types in 3.1.0; use ToWaveFormatExBytes, MarshalToPtr or MarshalFromPtr to cross a native boundary (#​1432)
  • Breaking: AudioClient.IsFormatSupported and WasapiPlayer.IsFormatSupported now return the closest-match format as out WaveFormat rather than out WaveFormatExtensible. WASAPI documents this format as either a WAVEFORMATEX or a WAVEFORMATEXTENSIBLE, and the old signature could only represent the latter — a plain format was previously decoded as a WaveFormatExtensible whose base fields were valid but whose extensible fields were meaningless. Callers needing the extensible fields should pattern-match (#​1425)
  • Fixed WaveIn/WaveOut failing under Native AOT with WaveHeaderUnprepared ("The wave header was not prepared"). The WAVEHDR was a [StructLayout] class passed to winmm by value, which CoreCLR pins in place but NativeAOT copies into a per-call temporary, so the driver's WHDR_PREPARED/WHDR_DONE/dwBytesRecorded writes were discarded. It is now a struct in a stable unmanaged block (#​1425)
  • Fixed ACM conversion failing under Native AOT — WaveFormatConversionStream, AcmStream and so Mp3FileReader and AudioFileReader. ACMSTREAMHEADER was a [StructLayout] class passed to msacm32 by value, and the codec keeps private state in the header's reserved fields between acmStreamPrepareHeader, acmStreamConvert and acmStreamUnprepareHeader; the AOT marshaller's per-call copy round-trips only the declared fields, so that state was lost and conversion failed. It is now a struct in a stable unmanaged block, as WAVEHDR already is (#​1425)
  • Fixed WaveFormat.MarshalToPtr and WaveFormat.MarshalFromPtr corrupting any WaveFormat subclass under Native AOT — the AOT marshaller drops the inherited WAVEFORMATEX fields of a class hierarchy, so a WaveFormatExtensible was written with its SubFormat GUID over the sample rate. Every remaining site that sized or wrote a WaveFormat with Marshal.SizeOf/StructureToPtr was converted too: WASAPI (AudioClient), Media Foundation (MFInitMediaTypeFromWaveFormatEx, reachable from MediaFoundationResampler/MediaFoundationEncoder), DMO (DmoMediaType.SetWaveFormat, MediaObject) and ACM (AcmStream, AcmDriver) (#​1425)
  • WaveFormat.MarshalToPtr now always allocates at least the 18 + cbSize bytes it advertises. A WaveFormat subclass that declares extraSize but doesn't write it in Serialize previously produced a block shorter than its own cbSize, which a native consumer would read past (#​1425)
  • Added WaveFormat.ToWaveFormatExBytes(), which renders a WaveFormat as a native WAVEFORMATEX byte array. MarshalToPtr is now a thin wrapper over it, for callers who need an unmanaged block rather than a buffer they already own (#​1425)
  • Added a Serialize override to Mp3WaveFormat, which previously advertised cbSize = 12 but wrote none of its 12 MPEGLAYER3WAVEFORMAT extra bytes (#​1425)
  • WaveFormatExtraData now sizes its buffer from cbSize instead of holding a fixed 100-byte array, so a fmt chunk declaring more than 100 bytes of extra data keeps it rather than having all of it discarded (#​482). The fixed size existed only because [MarshalAs(ByValArray, SizeConst = 100)] needed a compile-time length. ExtraData is now exactly ExtraSize bytes long rather than always 100 (#​1432)
  • NAudio.WinMM is now marked IsAotCompatible, and the AOT smoke test covers the winmm WAVEHDR/WAVEFORMATEX paths (#​1425)
  • Fixed Mp3FileReaderBase seeking silently restarting playback from the beginning of the file on MP3s with a Xing/Info header — the lazy frame index was gated on IsLengthExact, which such a header sets without any frame having been scanned. Also fixed seeks landing on the wrong frame when the target fell exactly on a frame boundary, and Xing/Info header frames being indexed as audio (shifting every seek in those files ~26 ms early). A 3.0.0 regression (#​1419)
  • Fixed WdlResamplingSampleProvider losing samples, and eventually returning 0 permanently, when asked for more output than the source could supply — a 3.0.0 regression that broke the common pattern of reading generously from a BufferedWaveProvider-backed capture chain. WdlResampler.ResampleOut also no longer drifts in input-driven (feed) mode when handed fewer samples than ResamplePrepare requested (#​1412)
  • Fixed two infinite loops in the WAV parser triggered by corrupt files declaring a negative chunk size. An RF64 ds64 chunk with a negative dataChunkLength, or a LIST/adtl sub-chunk with a negative size, made the chunk walk advance by zero bytes per iteration and spin at 100% CPU without throwing. Negative and oversized sizes are now rejected where they are read, and an undersized ds64 chunk throws FormatException rather than ArgumentOutOfRangeException (#​1428)
  • Fixed the NAudioConsoleTest WASAPI exclusive-mode quick scan reporting no supported formats at all on devices that support plenty — it built its probe formats with an empty WAVEFORMATEXTENSIBLE channel mask, which drivers such as Realtek reject outright. It now probes with the canonical layout for the channel count, the same mask the library's own format adaptation uses (#​1431)

3.0.1

A patch release. The headline fix is packaging: the NAudio and NAudio.Extras
meta-packages now ship a plain net9.0-windows leg, so WinForms and WPF projects
targeting netX.0-windows get the full Windows stack again.

  • Breaking: AudioFileReader now throws NotSupportedException instead of InvalidOperationException when the cross-platform build is asked for a format it cannot read, and the messages simply state that rather than suggesting an NAudio.Wasapi install that could never have helped (#​1407)
  • Fixed the NAudio and NAudio.Extras meta-packages resolving their portable net9.0 asset on projects targeting a plain netX.0-windows TFM (the WinForms/WPF template default), which silently dropped the entire Windows stack — no WaveOut, WASAPI, Media Foundation, ASIO, DMO or WinForms types, and AudioFileReader throwing "MP3 file reading requires the NAudio.Wasapi package". Both packages now also ship a plain net9.0-windows leg (#​1407)
  • Projects on a plain netX.0-windows TFM may now see CA1416 warnings when calling WASAPI process-loopback capture. The warning is correct — those callers do need an OperatingSystem.IsWindowsVersionAtLeast(10, 0, 19041) guard — and was previously hidden because the only Windows asset available already implied that floor (#​1407)
  • Sample and tool apps now roll forward onto newer .NET runtimes, so running them no longer requires the .NET 9 runtime to be installed (#​1408)
  • Fixed AiffFileReader reporting too long a Length and throwing IndexOutOfRangeException when the SSND chunk declares a non-zero offset (#​1405)
  • Fixed AiffFileReader.Read throwing IndexOutOfRangeException when the source stream returns fewer bytes than requested (#​1405)

3.0.0

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
  • NAudio is now a set of focused packages: NAudio.Core, NAudio.Midi, NAudio.WinMM, NAudio.Wasapi, NAudio.Asio, NAudio.Dmo, NAudio.WinForms, plus the new NAudio.Effects (shipped in NAudio.Core), NAudio.Sampler, NAudio.Vst3, NAudio.Alsa and NAudio.SoundFile. The NAudio meta-package still pulls the Windows stack together, so existing consumers see no change. See Docs/Architecture/NAudio3AssemblyLayoutPlan.md
  • NAudio.Core, NAudio.Midi, NAudio.Wasapi, NAudio.Dmo, NAudio.Sampler, NAudio.SoundFile and NAudio.Alsa are Native-AOT compatible (IsAotCompatible=true), enforced in CI by NAudioAotSmokeTest
  • NAudio.Wasapi targets plain net9.0 (Windows-only at runtime via [SupportedOSPlatform("windows")]), so cross-platform apps can reference it and build on Linux/macOS without EnableWindowsTargeting. The WinRT MIDI backend moved to NAudio.Midi, which now dual-targets net9.0;net9.0-windows10.0.19041.0 (#​1384)
  • The NAudio.Uap package is removed — use WasapiPlayerBuilder / WasapiRecorderBuilder
  • Packages ship with SourceLink, .snupkg symbol 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.Effects framework: IAudioEffect / EffectSampleProvider / EffectChain with 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 via WasapiPlayerBuilder / WasapiRecorderBuilder: IAudioClient3 low 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 AsioDevice replacing AsioOut: explicit playback/recording/duplex modes, non-contiguous channels, per-channel Span<float> callbacks, driver-reset recovery and per-buffer timing. AsioOut is preserved as a facade. See Docs/AsioMigration.md
  • Cross-platform audio files — new NAudio.SoundFile package: 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.Alsa package: AlsaOut (IWavePlayer) and AlsaIn (IWaveIn) plus AlsaDeviceEnumerator, backed by libasound. See Docs/PlayAudioFileLinuxAlsa.md and Docs/RecordAudioFileLinuxAlsa.md (#​1182)
  • VST 3 hosting — new NAudio.Vst3 package (Windows-only): discover, load and host VST 3 effects and instruments, with parameters, state and .vstpreset presets, native editor windows, program lists/units, latency compensation, and live/offline MIDI-file playback through the shared MIDI pipeline. See the NAudio.Vst3 README and Docs/Architecture/Vst3Hosting.md. VST is a registered trademark of Steinberg Media Technologies GmbH
  • Software sampler — new NAudio.Sampler package: polyphonic, cross-platform playback of SoundFont (.sf2) and SFZ instruments and single-sample instruments, rendered as an ISampleProvider (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 an MMDeviceNotificationClient exposing DeviceStateChanged, DeviceAdded, DeviceRemoved, DefaultDeviceChanged and PropertyValueChanged as 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 WinRT WinRTMidiIn / WinRTMidiOut and backend-agnostic IMidiInput / IMidiOutput; and a new IMidiInstrument seam (MidiFileSequence / SequencedMidiPlayer / OfflineMidiRenderer / LiveMidiInstrument) giving an end-to-end MIDI-file → audio pipeline that drives the sampler or a hosted VST 3 instrument. MidiFile also reads RIFF-RMID (.rmi) files (#​1236) and MidiFile.Export gains a Stream overload, thanks to @​MaKiPL (#​499)
  • Sequencing — a portable NAudio.Sequencing namespace in NAudio.Core (tempo and time-signature maps, transport, EventTimeline, swing, and a sample-accurate per-buffer dispatcher) underpinning MIDI-file playback and the sampler. See Docs/Architecture/Sequencing.md
  • Live capture mixing — new NAudio.Extras helpers CaptureMixerInput and RealtimeCaptureMixer capture 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 — AudioFileReader and CachedSound gain Stream constructors, 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). `StreamMed...

Description has been truncated

@dependabot dependabot Bot added dependencies Pull requests that update a dependency file .NET Pull requests that update .NET code labels Oct 20, 2026
dependabot Bot and others added 2 commits October 23, 2026 08:46
Bumps NAudio from 2.2.1 to 3.3.0
Bumps NAudio.Wasapi from 2.2.1 to 3.3.0

---
updated-dependencies:
- dependency-name: NAudio
  dependency-version: 3.3.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: nuget
- dependency-name: NAudio.Wasapi
  dependency-version: 3.3.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: nuget
...

Signed-off-by: dependabot[bot] <support@github.com>
NAudio 3.0 replaced Read(float[], int, int) with Read(Span<float>) on
ISampleProvider, so the mono downmix provider no longer compiled with
the 3.3.0 bump. Callers now pass the arrays as spans too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tobymarks
tobymarks force-pushed the dependabot/nuget/windows/src/Inlaut.App/nuget-c59eef05e7 branch from 766567a to bd7aa02 Compare October 23, 2026 06:46
tobymarks and others added 2 commits October 23, 2026 08:49
NAudio 3 declares MIT only as a nuspec license expression and no longer
ships a license file, so the installer build refused the package. Like
sherpa-onnx, its text now comes from a pinned upstream original whose
hash packaging verifies. NAudio 3 is split into Core, Midi, Wasapi and
WinMM packages, all listed in nuget-packages.json, and NAudio.Core pulls
in System.Numerics.Tensors, whose license and notices are copied from
the package.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The update test over beta.9 found NAudio.Asio.dll, NAudio.WinForms.dll and
the NAudio 2.2.1 license folder left behind: NAudio 3 no longer brings
those assemblies and keeps its license in the pinned licenses\naudio.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tobymarks
tobymarks merged commit 3b2264c into main Oct 23, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file .NET Pull requests that update .NET code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant