List the playback and recording devices in C#, find the system defaults, and open a particular device by its id, with the RecursiveAI.OneAudio.Devices package.
dotnet add package RecursiveAI.OneAudio --version 1.2.1 dotnet add package RecursiveAI.OneAudio.Devices --version 1.2.1
using OneAudio.Devices; // The operating system's audio API: WASAPI, Core Audio or ALSA. Console.WriteLine($"backend: {AudioDevices.Backend.Name}, " + $"available: {AudioDevices.IsAvailable}"); DeviceDirection[] directions = [DeviceDirection.Output, DeviceDirection.Input]; foreach (DeviceDirection direction in directions) { IReadOnlyList<AudioDeviceInfo> devices = AudioDevices.List(direction); AudioDeviceInfo? def = AudioDevices.Default(direction); Console.WriteLine($"{direction}: {devices.Count} devices, " + $"default: {def?.Id ?? "none"}"); } // Pick a device by part of its name. Id is what DeviceStreamOptions.DeviceId takes; // it is backend specific, so match on Name and pass Id through untouched: // new DeviceStreamOptions { DeviceId = d.Id }. string wanted = args.Length > 0 ? args[0] : "USB Audio"; foreach (AudioDeviceInfo d in AudioDevices.List(DeviceDirection.Output)) { if (!d.Name.Contains(wanted, StringComparison.OrdinalIgnoreCase)) continue; Console.WriteLine($"first output matching \"{wanted}\": {d.Id}"); Console.WriteLine($" {d.Name.Replace('\n', ' ')}"); break; }
backend: alsa, available: True Output: 90 devices, default: default Input: 45 devices, default: default first output matching "USB Audio": hw:CARD=Audio,DEV=0 USB Audio, USB Audio Direct hardware device without any conversions
This ran on a Linux desktop with PipeWire, a USB audio interface, a webcam and HDMI outputs. ALSA lists every PCM name it knows, plug-ins included, which is why the counts are high. On Windows and macOS the list is the endpoints you see in the system’s sound settings.
AudioDevices.List(direction)returns anAudioDeviceInfoper device:Id,Name,IsDefault, and, where the backend can tell,DefaultSampleRate,MaxChannelsandMinLatencyFrames. Call it from a control thread, never from an audio callback.Idis backend specific. On ALSA it’s a PCM name such asdefaultorhw:CARD=Audio,DEV=0; on Windows it’s the endpoint id. Don’t parse it; pass it toDeviceStreamOptions.DeviceId.- With no
DeviceId, a stream uses the system default and follows it when it changes.SelectDevice(id)moves an open output or input to another device;SelectDevice(null)goes back to the default. AudioDevices.DevicesChangedfires when devices are plugged in or removed, on WASAPI and Core Audio. ALSA has no hot-plug events, so on Linux read the list again when you need it.IsAvailableis false when the system’s audio library isn’t there, such as libasound on a server. Outputs then render silently and inputs deliver nothing.
Choosing a device and playing to it: Play audio in C#.