How to change default sound playback device programmatically?
Asked Answered
N

3

13

How to change the default default audio device for playback and recording in vista programmatically ?

Is there any registry setting for it like sound manager in window XP?

Which API does it?

Nonpareil answered 1/2, 2010 at 7:50 Comment(1)
you mean the default sound output? even for non-MCI playback?Opulent
C
8

There is no public API which allows you to change the default audio device, that is functionality that is considered to be under the users control. This has always been the case in Windows.

Having said that, if you search the web, there are a number of people who have reverse engineered the APIs that are used in Windows Vista to do this, but I'm not going to point you to them (the reverse engineered APIs are internal unsupported APIs and may change without notice from Microsoft). You use these solutions at your own peril.

Clique answered 3/2, 2010 at 18:56 Comment(1)
I converted the code from the link in the comment above in to C# and added some stuff, you can find it here as well: github.com/zivsha/SoundControlCustard
P
13

System Tray Audio Device Switcher uses "Software\Microsoft\Multimedia\Sound Mapper", "Playback" to set the index of the sound device which was obtained by enumeration the devices. mciSendCommand from "winmm.dll" is also used

In this source code you will find the registry keys used to achieve that.

If this doesn't work you could give Process Monitor a try and monitor all registry activities of windows when you change the default device. On my Vista installation the control panel twiddles with "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render\"

For Vista see http://www.vistaaudiochanger.com/

Purpura answered 7/2, 2010 at 13:27 Comment(0)
C
8

There is no public API which allows you to change the default audio device, that is functionality that is considered to be under the users control. This has always been the case in Windows.

Having said that, if you search the web, there are a number of people who have reverse engineered the APIs that are used in Windows Vista to do this, but I'm not going to point you to them (the reverse engineered APIs are internal unsupported APIs and may change without notice from Microsoft). You use these solutions at your own peril.

Clique answered 3/2, 2010 at 18:56 Comment(1)
I converted the code from the link in the comment above in to C# and added some stuff, you can find it here as well: github.com/zivsha/SoundControlCustard
P
7

I really don't know if anyone still needs this, but here is my solution. Actually, it's for the capture device, but it can be changed easily to the render device.

It sets 3 registry values in the device's key to the current time. Magic, but that's how it works. Note: only tested on Win7 x64

void SetDefaultRecordDevice(tstring strDeviceName){
    const int BUFF_LEN = 260;
    //HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Capture\{79434968-09f6-4dff-8086-c5e618b21473}\Role:0:
    //"DE 07 08 00 06 00 10 00 15 00 38 00 1E 00 48 03"
    HKEY hkCaptureDevices;
    RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\MMDevices\\Audio\\Capture") , 0, KEY_ENUMERATE_SUB_KEYS | KEY_WOW64_64KEY, &hkCaptureDevices);
    TCHAR lpwstrDeviceGuidKey[BUFF_LEN];
    DWORD dwDeviceGuidKeySize = BUFF_LEN;
    for(int i=0;RegEnumKeyEx(hkCaptureDevices, i, lpwstrDeviceGuidKey, &dwDeviceGuidKeySize, 0, 0, 0, 0) != ERROR_NO_MORE_ITEMS; ++i){
        dwDeviceGuidKeySize = BUFF_LEN;
        HKEY hkProps;
        RegOpenKeyEx(hkCaptureDevices, (tstring(lpwstrDeviceGuidKey) + _T("\\Properties")).c_str() , 0, KEY_READ | KEY_WOW64_64KEY, &hkProps);
        TCHAR data[BUFF_LEN];
        DWORD dwDataSize = BUFF_LEN;
        if(RegQueryValueEx(hkProps, _T("{a45c254e-df1c-4efd-8020-67d146a850e0},2"), 0, 0, (LPBYTE)data, &dwDataSize) !=  ERROR_SUCCESS){
            continue;
        } else {
            tstring strCurrentDeviceName(data);
            // TODO név általánosítás
            if(strDeviceName == strCurrentDeviceName){
                HKEY hkGuid;
                RegOpenKeyEx(hkCaptureDevices, lpwstrDeviceGuidKey , 0, KEY_READ | KEY_SET_VALUE | KEY_QUERY_VALUE | KEY_WOW64_64KEY | KEY_NOTIFY , &hkGuid);

                time_t CurrentTime;
                time(&CurrentTime);

                time_t     now = time(0);
                struct tm  tstruct;


                gmtime_s(&tstruct, &now);
                // Visit http://en.cppreference.com/w/cpp/chrono/c/strftime
                // for more information about date/time format

                char CustomRegistryDateValue[16];

                WORD year = tstruct.tm_year + 1900;
                WORD month = tstruct.tm_mon+1;
                WORD dayOfTheWeek = tstruct.tm_wday;
                WORD day = tstruct.tm_mday;
                WORD hour = tstruct.tm_hour;
                WORD minute = tstruct.tm_min;
                WORD second = tstruct.tm_sec;
                WORD millisec = 0x0; // hasrautés

                int k = 0;
                *((WORD*)CustomRegistryDateValue + k++) = year;
                *((WORD*)CustomRegistryDateValue + k++) = month;
                *((WORD*)CustomRegistryDateValue + k++) = dayOfTheWeek;
                *((WORD*)CustomRegistryDateValue + k++) = day;
                *((WORD*)CustomRegistryDateValue + k++) = hour;
                *((WORD*)CustomRegistryDateValue + k++) = minute;
                *((WORD*)CustomRegistryDateValue + k++) = second;
                *((WORD*)CustomRegistryDateValue + k++) = millisec;

                RegSetValueExA(hkGuid, ("Role:0"), 0, REG_BINARY, (LPBYTE)CustomRegistryDateValue, 16);
                RegSetValueExA(hkGuid, ("Role:1"), 0, REG_BINARY, (LPBYTE)CustomRegistryDateValue, 16);
                RegSetValueExA(hkGuid, ("Role:2"), 0, REG_BINARY, (LPBYTE)CustomRegistryDateValue, 16);
                RegFlushKey(hkGuid);
                RegCloseKey(hkGuid);
            }
        }
        RegCloseKey(hkProps);
    }
    RegCloseKey(hkCaptureDevices);
}
Pint answered 22/8, 2014 at 22:6 Comment(2)
Great! Working even in Windows 10Duwe
Actually this doesn't work, at least not in Windows 7/64. The Sound/Recording dialog does show the change in default recording device (if you reload it at least), but (reopened) WaveIn functions still get their data from the old device. So it appears to be a cosmetic change, internally things are not updated. Guess it needs more magic.Featherstone

© 2022 - 2024 — McMap. All rights reserved.