How can I programatically change the default audio device on a vista / win 7 system? Using C# or a Win API call?
-
2This is basically a duplicate of http://stackoverflow.com/questions/1334076/how-to-change-default-audio-input-device-programatically except input vs output device, either way, there is no API for it on Vista+ unless you want to decompile media center and find the undocumented stuff – Anders Jan 05 '11 at 01:09
3 Answers
The WinMM API should provide the functionality that you request.
You would use the DRVM_MAPPER_PREFERRED_SET message, which is sent with waveOutMessage() function.
Documentation: http://msdn.microsoft.com/en-us/library/aa909789.aspx
However, if you are trying to send the waveform sound out yourself, you should look at the WinMM.Net library.

- 265,109
- 74
- 539
- 565

- 48,783
- 32
- 145
- 190
-
2All I need to do is change the sound device on Windows, so that all audio routes through that device. Essentially I have a lot of sound devices on my system, and I want to replace the default sys tray app, so that I don't need to right click , open the device manager each time I need to switch a device. Will this API do this? – JL. Oct 12 '09 at 15:28
-
Yes, You can set the default audio playback device in XP with the DRVM_MAPPER_PREFERRED_SET message, which is sent with waveOutMessage(). This doesn't work in Vista. I am researching. – John Gietzen Oct 12 '09 at 16:04
-
Thanks, I think this last link will work, it should port to win 7 hopefully! – JL. Oct 12 '09 at 16:19
-
Love that last link! It's been driving nuts in Win7 having to launch the Playback devices dialog every time I want to switch from headphones to speakers, and vice-versa. Much easier now. Thanks! – Ecyrb Jan 04 '10 at 21:12
-
@Ecyrb how exactly did you do that ? WinMM.net doesn't seem to have waveOutMessage functionality. In fact native library import for waveOutMessage is surrounded with #if false preprocessor directive. – Alexander Apr 15 '11 at 17:56
-
Jonathan Sampson removed the link to http://www.vistaaudiochanger.com/ because it's inactive. That sucks. I didn't play with WinMM.net. – Ecyrb Apr 16 '11 at 16:31
-
In fact `DRVM_MAPPER_PREFERRED_SET` doesn't work even on XP, [it returns](http://www.microsoft-questions.com/microsoft/Win32-DirectX-Audio/30558445/how-to-send-waveoutmessage-drvmmapperpreferredset-from-net-pro.aspx) `MMSYSERR_INVALPARAM`. And documentation that you linked to clearly states it's for Windows Mobile. – user Feb 22 '16 at 23:36
This can now (actually for quite some time already) be done very easily using the AudioSwitcher.AudioApi.CoreAudio NuGet package.
Simply create a new CoreAudioController
:
var controller = new AudioSwitcher.AudioApi.CoreAudio.CoreAudioController();
Get hold of the desired device using its GUID:
var device = controller.GetDevice(Guid.Parse(...));
And lastly set it as the default playback device:
controller.DefaultPlaybackDevice = device;

- 1,045
- 10
- 27
-
I get error CS0200: Property or indexer 'AudioController
.DefaultPlaybackDevice' cannot be assigned to -- it is read only – Ken Netherland Aug 03 '23 at 18:25 -
Okay so the API has changed but I can't get playbackDevice.SetAsDefault() to work either. Always returns false. – Ken Netherland Aug 03 '23 at 19:20
-
@KenNetherland I'd suggest you open an issue on their GitHub page then, StackOverflow comments are usually not the best place to find answers to problems like these ;) – kwyntes Aug 04 '23 at 17:41
I found the AudioSwitcher
constructor to be extra slow in my case.
I suggest using the "CoreAudio" API for managing audio devices.
Here is a current wrapper library available on NuGet. https://github.com/morphx666/CoreAudio/tree/master
Set device:
public static void SetDefaultDevice(string id) {
MMDeviceEnumerator deviceEnum = new MMDeviceEnumerator(Guid.NewGuid());
MMDevice device = deviceEnum.GetDevice(id);
deviceEnum.SetDefaultAudioEndpoint(device);
}
Get devices
public static MMDeviceCollection GetAudioDevices() {
MMDeviceEnumerator deviceEnum = new MMDeviceEnumerator(Guid.NewGuid());
return deviceEnum.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active);
}

- 11
- 1
- 1