NLayer.NAudioSupport
3.0.0
dotnet add package NLayer.NAudioSupport --version 3.0.0
NuGet\Install-Package NLayer.NAudioSupport -Version 3.0.0
<PackageReference Include="NLayer.NAudioSupport" Version="3.0.0" />
<PackageVersion Include="NLayer.NAudioSupport" Version="3.0.0" />
<PackageReference Include="NLayer.NAudioSupport" />
paket add NLayer.NAudioSupport --version 3.0.0
#r "nuget: NLayer.NAudioSupport, 3.0.0"
#:package NLayer.NAudioSupport@3.0.0
#addin nuget:?package=NLayer.NAudioSupport&version=3.0.0
#tool nuget:?package=NLayer.NAudioSupport&version=3.0.0
NLayer
NLayer is a fully managed, MIT-licensed MP3 to WAV decoder implemented in C# based on the MPEG specifications.
NLayer targets netstandard2.0 and net8.0, so it runs on .NET Framework 4.6.1+, .NET 8+, Unity, and Mono.
NLayer.NAudioSupport targets net9.0, because NAudio 3 does — see
Which NLayer.NAudioSupport version? below.
Usage
To use NLayer for decoding MP3, first reference NLayer.
using NLayer;
Then create an MpegFile, pass a file name or a stream to the constructor, and use ReadSamples for decoding the content:
// samples per second times channel count
const int samplesCount = 44100;
var fileName = "myMp3File.mp3";
var mpegFile = new MpegFile(filename);
float[] samples = new float[samplesCount];
int readCount = mpegFile.ReadSamples(samples, 0, samplesCount);
More information could be found in code documents.
Use with NAudio
NLayer is capable of using in conjunction with NAudio for file conversion and real-time playback.
You need to reference NAudio, NLayer and NLayer.NAudioSupport first.
using NAudio.Wave;
using NLayer.NAudioSupport;
Then create an Mp3FileReader, passing in a FrameDecompressorBuilder that uses the Mp3FrameDecompressor from NLayer.NAudioSupport:
var fileName = "myMp3File.mp3";
var builder = new Mp3FileReader.FrameDecompressorBuilder(wf => new Mp3FrameDecompressor(wf));
var reader = new Mp3FileReaderBase(fileName, builder);
// play or process the file, e.g.:
waveOut.Init(reader);
waveOut.Play();
Which NLayer.NAudioSupport version?
NAudio 3 dropped .NET Framework and netstandard2.0: NAudio.Core 3.x ships a
single net9.0 assembly. NLayer.NAudioSupport therefore comes in two lines,
and picking the wrong one is not a compile error — NuGet will happily unify
NAudio.Core up to 3.x behind the rest of an NAudio 2 install and fail at
runtime instead.
| NLayer.NAudioSupport | Targets | Works with |
|---|---|---|
| 3.x | net9.0 |
NAudio 3 |
| 2.x | netstandard2.0, net8.0 |
NAudio 2 |
If you are still on NAudio 2, or need .NET Framework / Unity / Mono, stay on
NLayer.NAudioSupport 2.x. The NLayer package itself is unaffected: it is
still netstandard2.0 and net8.0 on both lines, so the decoder remains
available everywhere it always was.
On 3.x, Mp3FrameDecompressor and ManagedMpegStream implement NAudio 3's
Span<byte> overloads directly, so decoding does not bounce through a pooled
byte[]. MpegFile and MpegFrameDecoder gained matching Span<T> overloads
for that; they are compiled into the net8.0 asset only, so the
netstandard2.0 build stays free of a System.Memory dependency.
Building
dotnet build NLayer.sln -c Release
dotnet test NLayer.sln -c Release
Every push and pull request is built and tested by the build GitHub Actions
workflow.
Assemblies are strong-named with NLayerStrongNameKey.snk (checked into the
repo root). Compiler warnings are treated as errors; the broader .NET
code-analysis (CA) analyzers are not enabled — turning them on surfaces ~110
mostly-mechanical style/perf suggestions that can be addressed incrementally.
Releasing
Versioning is centralised in Directory.Build.props (<VersionPrefix>) and
shared by both the NLayer and NLayer.NAudioSupport packages. Release notes
live in RELEASE_NOTES.md. Packages are published to NuGet by the release
workflow, which uses NuGet trusted publishing (OIDC) — no API key is stored in
the repository.
- Pre-release: run the
releaseworkflow manually (Actions → release → Run workflow) frommain. It publishes<VersionPrefix>-preview.<run>, or pass amilestonesuch asrc.1for<VersionPrefix>-rc.1. - Final release: bump
<VersionPrefix>, rename the### Unreleasedheading inRELEASE_NOTES.mdto### <version> (DD MMM YYYY), commit, then push a matchingv<version>tag (e.g.v2.0.0). The workflow packs, pushes to NuGet, and creates a GitHub Release.
See Docs/Releasing.md for the full step-by-step guide,
trusted-publishing setup, and troubleshooting.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net9.0
- NAudio.Core (>= 3.0.1)
- NLayer (>= 3.0.0)
NuGet packages (5)
Showing the top 5 NuGet packages that depend on NLayer.NAudioSupport:
| Package | Downloads |
|---|---|
|
MappingTools.Core
osu! mapping utility library built for Mapping Tools. |
|
|
LMSupply.Transcriber
Local speech-to-text transcription using Whisper models with ONNX Runtime. Zero-configuration, automatic GPU acceleration, and lazy model downloading. |
|
|
Eyu.Audio
Package Description |
|
|
KevInc.UbiArt.Raki
Monolithic UbiArt RAKI audio wrapper parsing, encoding, and NAudio-backed codec adapters. |
|
|
mdimai666.Mars.PlayAudioNodePlugin
Mars.PlayAudioNodePlugin - provide play audio functions for Mars - Play audio - List output devices |
GitHub repositories (5)
Showing the top 5 popular GitHub repositories that depend on NLayer.NAudioSupport:
| Repository | Stars |
|---|---|
|
openutau/OpenUtau
Open singing synthesis platform / Open source UTAU successor
|
|
|
ValveResourceFormat/ValveResourceFormat
Source 2 Viewer is an all-in-one tool to browse VPK archives, view, extract, and decompile Source 2 assets, including maps, models, materials, textures, sounds, and more.
|
|
|
leezer3/OpenBVE
OpenBVE- A free train simulator
|
|
|
LiuYunPlayer/TuneLab
|
|
|
vocoder712/OpenUtauMobile
OpenUtau Mobile 是一个面向移动端的开源免费歌声合成软件; OpenUtau Mobile is a free and open-source singing voice synthesis software for mobile devices.
|
| Version | Downloads | Last Updated |
|---|---|---|
| 3.0.0 | 1,189 | 8/27/2026 |
| 2.0.1 | 9,117 | 7/6/2026 |
| 2.0.0 | 562 | 6/28/2026 |
| 2.0.0-preview.3 | 88 | 6/26/2026 |
| 2.0.0-preview.2 | 80 | 6/26/2026 |
| 1.4.0 | 374,313 | 12/18/2023 |
| 1.3.0 | 125,137 | 9/7/2021 |
| 1.2.0 | 14,600 | 2/8/2021 |
| 1.1.0 | 86,503 | 3/9/2020 |
| 1.0.0 | 88,268 | 2/4/2017 |
- **`NLayer.NAudioSupport` now targets NAudio 3** (`NAudio.Core` 3.0.1). NAudio 3
dropped .NET Framework and `netstandard2.0`, so this package is now `net9.0`
only. Consumers on NAudio 2, .NET Framework, Unity or Mono should stay on
`NLayer.NAudioSupport` 2.x — mixing 3.x with an NAudio 2 install resolves
`NAudio.Core` up to 3.x and fails at runtime rather than at compile time.
- `NLayer` itself is unchanged and still targets `netstandard2.0` and `net8.0`,
so the decoder remains available on every platform it already supported. The
major version bump only reflects the lockstep versioning of the two packages.
- `Mp3FrameDecompressor` and `ManagedMpegStream` now implement NAudio 3's
`Span<byte>` overloads (`IMp3FrameDecompressor.DecompressFrame` and
`Stream.Read`) directly. NAudio 3 calls the span overload for every frame, and
its default implementation rents a pooled `byte[]` and copies through it; that
round trip is now gone.
- `MpegFile.ReadSamples` and `MpegFrameDecoder.DecodeFrame` gained `Span<byte>`
and `Span<float>` overloads to support the above. They are compiled into the
`net8.0` asset only, so the `netstandard2.0` build keeps its dependency-free
package graph.
- Added tests covering the NAudio bridge (`Mp3FrameDecompressor`,
`ManagedMpegStream` and `Mp3FileReaderBase` end to end) against NAudio 3, and
tests pinning the span paths to byte-for-byte parity with the array ones.
- Fixed reading from a non-seekable stream, broken since 2.0.1. Such a stream has
no known sample count, which the end-of-stream trimming added in 2.0.1
represented as `long.MaxValue`; subtracting the read position from it and
truncating to `int` wrapped negative, so the very first read threw
`ArgumentOutOfRangeException`.