Jump to content

change Audio Volume for specific Audio Device (microphone and speaker)

Recommended Posts

Hi all,

I have multiple Audio-Devices connected to my PC (USB-Audio-Interface, USB-Microphone)

I want to change the volume for a specific audio device by its name (WDM-Name), even if its not the current active, or current default device)

Do you have some script for me?

Thanks all in advance

Link to post
Share on other sites

thank you for your fast answer,

I tried to open your sourcecode and find the part for changing the volume, but it's to advanced for me.
Could you give me a hint, or better a codesnippet? would be great :)

Link to post
Share on other sites

goodness !, ...it was a mashup of code I've found in the forum. I don't understand it myself but is functional as it is and I believe is what you were looking for.
The audio device is what is selected via the script and chooses a mic. to match the audio out.
I don't change the volume in the code, but the code calls for the volume interface windows had in win7 and from there I change the volume of each app. that may be open.

Link to post
Share on other sites

Here what you may looking for

#include <Constants.au3>

Opt("MustDeclareVars", 1)

Global Enum $eRender, $eCapture, $eAll
Global Const $STGM_READ = 0
Global Const $CLSCTX_INPROC_SERVER = 0x01

Global Const $PKEY_DEVICE_INTERFACE_FRIENDLY_NAME = "{026E516E-B814-414B-83CD-856D6FEF4822}, 2"
Global Const $PKEY_DEVICE_FRIENDLY_NAME = "{A45C254E-DF1C-4EFD-8020-67D146A850E0}, 14"
Global Const $PKEY_AUDIO_ENDPOINT_GUID = "{1DA5D803-D492-4EDD-8C23-E0C0FFEE7F0E}, 4"
Global Const $PKEY_DEVICE_DESCRIPTION = "{A45C254E-DF1C-4EFD-8020-67D146A850E0}, 2"
Global Const $PKEY_SYSTEM_NAME = "{B3F8FA53-0004-438E-9003-51A46E139BFC}, 6"

Global Const $sCLSID_MMDeviceEnumerator = "{BCDE0395-E52F-467C-8E3D-C4579291692E}"
Global Const $sIID_IMMDeviceEnumerator = "{A95664D2-9614-4F35-A746-DE8DB63617E6}"
Global Const $sTagIMMDeviceEnumerator = _
    "EnumAudioEndpoints hresult(int;dword;ptr*);" & _
    "GetDefaultAudioEndpoint hresult(int;int;ptr*);" & _
    "GetDevice hresult(wstr;ptr*);" & _
    "RegisterEndpointNotificationCallback hresult(ptr);" & _
    "UnregisterEndpointNotificationCallback hresult(ptr)"

Global Const $sIID_IMMDeviceCollection = "{0BD7A1BE-7A1A-44DB-8397-CC5392387B5E}"
Global Const $sTagIMMDeviceCollection = "GetCount hresult(uint*);Item hresult(uint;ptr*)"

Global Const $sIID_IMMDevice = "{D666063F-1587-4E43-81F1-B948E807363F}"
Global Const $sTagIMMDevice = _
    "Activate hresult(struct*;dword;ptr;ptr*);" & _
    "OpenPropertyStore hresult(dword;ptr*);" & _
    "GetId hresult(wstr*);" & _
    "GetState hresult(dword*)"

Global Const $sIID_IPropertyStore = "{886d8eeb-8cf2-4446-8d02-cdba1dbdcf99}"
Global Const $sTagIPropertyStore = _
    "GetCount hresult(dword*);" & _
    "GetAt    hresult(dword;ptr*);" & _
    "GetValue hresult(struct*;variant*);" & _
    "SetValue hresult(struct*;variant*);" & _
    "Commit   hresult();"

Global Const $sIID_IAudioEndpointVolume = "{5CDF2C82-841E-4546-9722-0CF74078229A}"
Global Const $sTagIAudioEndpointVolume = _
    "RegisterControlChangeNotify hresult(ptr);" & _
    "UnregisterControlChangeNotify hresult(ptr);" & _
    "GetChannelCount hresult(uint*);" & _
    "SetMasterVolumeLevel hresult(float;ptr);" & _
    "SetMasterVolumeLevelScalar hresult(float;ptr);" & _
    "GetMasterVolumeLevel hresult(float*);" & _
    "GetMasterVolumeLevelScalar hresult(float*);" & _
    "SetChannelVolumeLevel hresult(uint;float;ptr);" & _
    "SetChannelVolumeLevelScalar hresult(uint;float;ptr);" & _
    "GetChannelVolumeLevel hresult(uint;float*);" & _
    "GetChannelVolumeLevelScalar hresult(uint;float*);" & _
    "SetMute hresult(int;ptr);" & _
    "GetMute hresult(int*);" & _
    "GetVolumeStepInfo hresult(uint*;uint*);" & _
    "VolumeStepUp hresult(ptr);" & _
    "VolumeStepDown hresult(ptr);" & _
    "QueryHardwareSupport hresult(dword*);" & _
    "GetVolumeRange hresult(float*;float*;float*)"

Local $oIMMDeviceEnumerator = ObjCreateInterface($sCLSID_MMDeviceEnumerator, $sIID_IMMDeviceEnumerator, $sTagIMMDeviceEnumerator)
If Not IsObj($oIMMDeviceEnumerator) Then Exit ConsoleWrite("Error Device Enumerator" & @CRLF)

Local $oIMMDevice = GetDeviceByDescription($oIMMDeviceEnumerator, "Haut-parleurs")
If @error Then Exit ConsoleWrite ("Device not found" & @CRLF)

SetDeviceVolume($oIMMDevice, 50)

Func GetDeviceByDescription(ByRef $oIMMDeviceEnumerator, $sDescription)
  Local $pIMMDeviceCollection, $oIMMDeviceCollection
  If FAILED($oIMMDeviceEnumerator.EnumAudioEndpoints($eAll, $DEVICE_STATEMASK_ALL, $pIMMDeviceCollection)) Then
    Exit ConsoleWrite("Error EnumAudioEndpoints" & @CRLF)

  $oIMMDeviceCollection = ObjCreateInterface($pIMMDeviceCollection, $sIID_IMMDeviceCollection, $sTagIMMDeviceCollection)
  If Not IsObj($oIMMDeviceCollection) Then Exit ConsoleWrite("Error IMMDeviceCollection" & @CRLF)

  Local $iCount
  If FAILED($oIMMDeviceCollection.GetCount($iCount)) Then Exit ConsoleWrite("Error GetCount" & @CRLF)

  Local $pIMMDevice, $oIMMDevice, $pPropertyStore, $oPropertyStore
  For $i = 0 To $iCount - 1
    If FAILED($oIMMDeviceCollection.Item($i, $pIMMDevice)) Then Exit ConsoleWrite("Error collection Item" & @CRLF)
    $oIMMDevice = ObjCreateInterface($pIMMDevice, $sIID_IMMDevice, $sTagIMMDevice)
    If Not IsObj($oIMMDevice) Then ConsoleWrite("Error IMMDevice object" & @CRLF)
    If FAILED($oIMMDevice.OpenPropertyStore($STGM_READ, $pPropertyStore)) Then Exit ConsoleWrite("Property Store" & @CRLF)
    $oPropertyStore = ObjCreateInterface($pPropertyStore, $sIID_IPropertyStore, $sTagIPropertyStore)
    If Not IsObj($oPropertyStore) Then Exit ConsoleWrite("Error property store Object" & @CRLF)
    ConsoleWrite("Friendly name = " & __PropertyStore_GetValue($oPropertyStore, $PKEY_DEVICE_FRIENDLY_NAME) & @CRLF)
    ConsoleWrite("Audio endpoint GUID = " & __PropertyStore_GetValue($oPropertyStore, $PKEY_AUDIO_ENDPOINT_GUID) & @CRLF)
    ConsoleWrite("Device Description = " & __PropertyStore_GetValue($oPropertyStore, $PKEY_DEVICE_DESCRIPTION) & @CRLF)
    ConsoleWrite("Interface friendly Name = " & __PropertyStore_GetValue($oPropertyStore, $PKEY_DEVICE_INTERFACE_FRIENDLY_NAME) & @CRLF)
    ConsoleWrite("System Name = " & __PropertyStore_GetValue($oPropertyStore, $PKEY_SYSTEM_NAME) & @CRLF)
    ConsoleWrite("=====================================================" & @CRLF)
    If __PropertyStore_GetValue($oPropertyStore, $PKEY_DEVICE_DESCRIPTION) = $sDescription Then Return $oIMMDevice
  Return SetError(101)
EndFunc   ;==>GetDeviceByDescription

Func SetDeviceVolume (ByRef $oIMMDevice, $fVolume) ; volume between 0 to 100
  $fVolume = ($fVolume < 0 ? 0 : ($fVolume > 100 ? 1 : $fVolume/100))
  Local $pIAudioEndpointVolume, $oIAudioEndpointVolume
  If FAILED($oIMMDevice.Activate(__uuidof($sIID_IAudioEndpointVolume), $CLSCTX_INPROC_SERVER, 0, $pIAudioEndpointVolume)) Then
    Exit ConsoleWrite ("Error Audio End Point Volume" & @CRLF)
  $oIAudioEndpointVolume = ObjCreateInterface($pIAudioEndpointVolume, $sIID_IAudioEndpointVolume, $sTagIAudioEndpointVolume)
  If Not IsObj($oIAudioEndpointVolume) Then Exit ConsoleWrite ("Error Audio End Point Object" & @CRLF)
  Local $fMasterVolumeLevel
  ConsoleWrite ("Master Volume Level = " & $fMasterVolumeLevel*100 & @CRLF)
  Local $bMute
  ConsoleWrite("Mute = " & $bMute & @CRLF)
  $oIAudioEndpointVolume.SetMasterVolumeLevelScalar($fVolume, 0)

Func FAILED($hr)
  Return ($hr < 0)
EndFunc   ;==>FAILED

Func __uuidof($sGUID)
  Local $tGUID = DllStructCreate("ulong Data1;ushort Data2;ushort Data3;byte Data4[8]")
  DllCall("ole32.dll", "long", "CLSIDFromString", "wstr", $sGUID, "struct*", $tGUID)
  If @error Then Return SetError(@error, @extended, 0)
  Return $tGUID
EndFunc   ;==>__uuidof

Func _Exit()
EndFunc   ;==>_Exit

Func __PropertyStore_GetValue($oIPropertyStore, $sPKey_GUID)
  Local $iErr = 0, $hRes = 0
  Local $tPKey, $vProp = ""
  If IsObj($oIPropertyStore) Then
    $tPKey = __WinAPI_PKEYFromString($sPKey_GUID)
    $hRes = $oIPropertyStore.GetValue($tPKey, $vProp)
    If $hRes Then $iErr = 2
    $iErr = 1
    $hRes = 99
  Return SetError($iErr, $hRes, $vProp)
EndFunc   ;==>__PropertyStore_GetValue

Func __WinAPI_PKEYFromString($sPKEY, $pID = Default)
  Local $tPKey = DllStructCreate("byte GUID[16]; dword PID;")
  DllCall("propsys.dll", "long", "PSPropertyKeyFromString", "wstr", $sPKEY, "struct*", $tPKey)
  If $pID <> Default Then DllStructSetData($tPKey, "PID", $pID)
  Return $tPKey
EndFunc   ;==>__WinAPI_PKEYFromString


Edited by Nine
corrected a small bug
Link to post
Share on other sites
40 minutes ago, atvaxn said:

Would be great, if you could check it one more time

What would also be great would be if you could include any of the ConsoleWrite statements generated by the code.

To see these you need to compile with the /console option or add the line

#pragma compile(Console, True)

to the top of the code.

Code hard, but don’t hard code...

Link to post
Share on other sites

Sorry but it is working for me.  Hard to solve something that isn't broken.  You will have to provide me with a bit more information than that...

Link to post
Share on other sites

The script works for any audio device, except the realteks "Lautsprecher"
I use a  german-windows and the speaker of the realtek-driver is named "Lautsprecher".

For some reason, nothing happens when using:
Local $oIMMDevice = GetDeviceByDescription($oIMMDeviceEnumerator, "Lautsprecher")

But it works when renaming "Lautsprecher" to "Lautsprecher2" or any other name...

Really strange

Link to post
Share on other sites

Ok.  It may be because there was any of the various forms of space at the end or beginning of the name.  When you renamed it, you must have erase that hidden char.

Edited by Nine
Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Create New...