NAudio only plays sound on the default output device

37 Views Asked by At

I have 3 devices available on my windows 10 audio list. Whenever I play a sound with WaveOut. It only plays on the device selected in that windows setting. It only plays the sound on the default output device.

static void Main(string[] args)
{
    MMDeviceEnumerator enumerator = new MMDeviceEnumerator();
    MMDeviceCollection devices = enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active);

    var allDevices = devices.ToList();

    var testFile = new WaveFileReader("./test.wav");

    for (int i = 0; i < allDevices.Count; i++)
    {
        var device = allDevices[i];

        Console.WriteLine("Using device: " + device.DeviceFriendlyName + ", " + device.FriendlyName);

        var waveout = new WaveOut();

        waveout.Init(testFile);
        waveout.DeviceNumber = i;
        waveout.Play();

        Thread.Sleep(4000);

        waveout.Stop();
        waveout.Dispose();
        waveout = null;
    }
}
1

There are 1 best solutions below

0
John On

I am answering my own question to save someone else time in the future since I didn't see these answers in the other NAudio related threads.

The testFile is a FileReader so it needs to be rewound with Seek() before every use. That is why it only played sound once.

The WavOut.DeviceNumber must be set before WaveOut.Init() is called or it doesn't take effect.

Lastly, the Device Number you must use changes depending on what device you have set as the default audio output device in your windows setting. If I find a solution for that. I'll post it later.

Here is the working solution:

static void Main(string[] args)
{
    MMDeviceEnumerator enumerator = new MMDeviceEnumerator();
    MMDeviceCollection devices = enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active);

    var allDevices = devices.ToList();


    var testFile = new WaveFileReader("./test.wav");

    for (int i = 0; i < allDevices.Count; i++)
    {
        var device = allDevices[i];

        Console.WriteLine("Using device: " + device.DeviceFriendlyName + ", " + device.FriendlyName);

        testFile.Seek(0, System.IO.SeekOrigin.Begin);

        var waveout = new WaveOut();

        waveout.DeviceNumber = i;
        waveout.Init(testFile);
        waveout.Play();

        Thread.Sleep(4000);

        waveout.Stop();
        waveout.Dispose();
    }
}

edit: You can get correct device number by using WaveOut.GetCapabilities(). It returns the correct device based on the index you provide, so you can use it to find out the real device numbers.