Docs/PlayAudioFileLinuxAlsa.md
On Linux there is no WASAPI or WaveOut. The NAudio.Alsa package adds
AlsaOut, an IWavePlayer that plays through ALSA. It is referenced
explicitly (it is not part of the NAudio meta-package, and the runtime
needs libasound — sudo apt install libasound2):
dotnet add package NAudio.Alsa
AlsaOut plays any IWaveProvider, so the format you can play depends
on the reader you give it. AudioFileReader, Mp3FileReader and
MediaFoundationReader are Windows-only; on Linux use the cross-platform
NAudio.Core readers (WaveFileReader, AiffFileReader,
RawSourceWaveStream) for PCM, and the NAudio.SoundFile package's
SoundFileReader for FLAC/Ogg/Opus/MP3 (see below). So for a WAV file,
use WaveFileReader:
using NAudio.Wave;
using NAudio.Wave.Alsa;
using (var audioFile = new WaveFileReader("test.wav"))
using (var outputDevice = new AlsaOut()) // default device
{
outputDevice.Init(audioFile);
outputDevice.Play();
while (outputDevice.PlaybackState == PlaybackState.Playing)
{
Thread.Sleep(200);
}
}
To play to a specific device, pass an ALSA PCM name to the constructor,
or pick one from the enumerator. Prefer default or a plughw: name
for arbitrary sample rates/formats — those go through ALSA's plug layer,
which converts; a bare hw: device only accepts rates and formats it
supports natively (the backend negotiates the nearest rate but will not
resample):
foreach (var device in AlsaDeviceEnumerator.GetPlaybackDevices())
{
Console.WriteLine($"{device.Name} - {device.Description}");
}
// var outputDevice = new AlsaOut("sysdefault:CARD=PCH");
The cross-platform NAudio.SoundFile
package is the Linux equivalent of MediaFoundationReader: its
SoundFileReader (a WaveStream / ISampleProvider over libsndfile)
decodes FLAC, Ogg-Vorbis, Opus and MP3. It needs a system libsndfile
(sudo apt install libsndfile1); SoundFileCapabilities reports which
codecs the installed build supports:
// dotnet add package NAudio.SoundFile
using NAudio.SoundFile;
using var audioFile = new SoundFileReader("test.flac");
using var outputDevice = new AlsaOut();
outputDevice.Init(audioFile);
outputDevice.Play();
(AAC/M4A/ALAC/WMA remain out of scope — that is FFmpeg territory.)
Alternatively, MP3 alone can be played with no native dependency by
plugging a fully-managed frame decompressor such as
NLayer into Mp3FileReaderBase:
// dotnet add package NLayer.NAudioSupport
using NLayer.NAudioSupport;
using var mp3 = new Mp3FileReaderBase("test.mp3",
waveFormat => new Mp3FrameDecompressor(waveFormat));
using var outputDevice = new AlsaOut();
outputDevice.Init(mp3);
outputDevice.Play();
AlsaOut.Volume is a software gain (1.0f = unity), so you can set it
before or during playback. Handle PlaybackStopped to be notified when
playback ends or fails — its Exception is null on a normal end of
stream or an explicit Stop().