Jump to content

Control *Application* Sound Volume?


DrLarch
 Share

Recommended Posts

I've been digging around and haven't found a way to control individual application sound volume with AutoIt. And I do mean without having bring up the sndvol.exe GUI and do it with keystrokes. Instead I mean like how the SoundSetWaveVolume() function can do this for the main volume.

Yeah, there's a command line tool NirCmd, but I'm hoping to find some way of doing it natively via AutoIt.

There is some C# code on Stack Overflow which claims to do it using the volume controls of the Core Audio API, but that's beyond my current skills. So hoping someone out there has an idea on this.

Thanks

Edited by DrLarch
Link to comment
Share on other sites

Here you go - tested with WIN7 and AIMP

special thanks goes to DanyfireX for the sounddetect code 

#include-once
;https://www.autoitscript.com/forum/topic/174460-is-there-a-way-to-detect-any-sound-file-played/
;Special Thanks to Danyfirex 02/08/2015
#include <WinAPIProc.au3>

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_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_IAudioSessionManager2 = "{77aa99a0-1bd6-484f-8bc7-2c654c9a9b6f}"
Global Const $sTagIAudioSessionManager = "GetAudioSessionControl hresult(ptr;dword;ptr*);" & _
        "GetSimpleAudioVolume hresult(ptr;dword;ptr*);"
Global Const $sTagIAudioSessionManager2 = $sTagIAudioSessionManager & "GetSessionEnumerator hresult(ptr*);" & _
        "RegisterSessionNotification hresult(ptr);" & _
        "UnregisterSessionNotification hresult(ptr);" & _
        "RegisterDuckNotification hresult(wstr;ptr);" & _
        "UnregisterDuckNotification hresult(ptr)"

Global Const $sIID_IAudioSessionEnumerator = "{e2f5bb11-0570-40ca-acdd-3aa01277dee8}"
Global Const $sTagIAudioSessionEnumerator = "GetCount hresult(int*);GetSession hresult(int;ptr*)"

Global Const $sIID_IAudioSessionControl = "{f4b1a599-7266-4319-a8ca-e70acb11e8cd}"
Global Const $sTagIAudioSessionControl = "GetState hresult(int*);GetDisplayName hresult(ptr);" & _
        "SetDisplayName hresult(wstr);GetIconPath hresult(ptr);" & _
        "SetIconPath hresult(wstr;ptr);GetGroupingParam hresult(ptr*);" & _
        "SetGroupingParam hresult(ptr;ptr);RegisterAudioSessionNotification hresult(ptr);" & _
        "UnregisterAudioSessionNotification hresult(ptr);"

Global Const $sIID_IAudioSessionControl2 = "{bfb7ff88-7239-4fc9-8fa2-07c950be9c6d}"
Global Const $sTagIAudioSessionControl2 = $sTagIAudioSessionControl & "GetSessionIdentifier hresult(ptr)" & _
        "GetSessionInstanceIdentifier hresult(ptr);" & _
        "GetProcessId hresult(dword*);IsSystemSoundsSession hresult();" & _
        "SetDuckingPreferences hresult(bool);"

; http://answers.awesomium.com/questions/3398/controlling-the-sound-using-pinvoke-the-volume-mix.html
Global Const $sIID_ISimpleAudioVolume = "{87CE5498-68D6-44E5-9215-6DA47EF883D8}"
Global Const $sTagISimpleAudioVolume = _
        "SetMasterVolume hresult(float;ptr);" & _
        "GetMasterVolume hresult(float*);" & _
        "SetMute hresult(int;ptr);" & _
        "GetMute hresult(int*)"

Global $__oIAudioSessionManager2


$SoundAPP = "AIMP.exe"
$newValue = Random ( 1,100,1 )
MsgBox ( 64,"","new random value: " & $newValue, 1 )
Local $CurrentVolume = Audio_GetMasterVolume(_GetProcessID_by_name($SoundAPP)) * 100


If $CurrentVolume <> $newValue And $CurrentVolume > $newValue Then
        For $i = $CurrentVolume To $newValue Step -1
            Audio_SetMasterVolume(_GetProcessID_by_name($SoundAPP), $i / 100)
            Sleep(30)
        Next
Else
        For $i = $CurrentVolume To $newValue Step +1
            Audio_SetMasterVolume(_GetProcessID_by_name($SoundAPP), $i / 100)
            Sleep(30)
        Next
EndIf


Func _GetProcessID_by_name($process_name)
    Local $Process_list = ProcessList()
    Local $ProcessID_Func = 0
    For $i = 1 To UBound($Process_list) - 1
        If $Process_list[$i][0] = $process_name Then
            $ProcessID_Func = $Process_list[$i][1]
            ExitLoop
        EndIf
    Next
Return  $ProcessID_Func
EndFunc   ;==>_SoundAPP_setVolume

Func Audio_SetMasterVolume($pid, $value)
    If Not IsObj($__oIAudioSessionManager2) Then
        $__oIAudioSessionManager2 = Audio_GetIAudioSessionManager2()
    EndIf
    If Not IsObj($__oIAudioSessionManager2) Then Return

    Local $pIAudioSessionEnumerator, $oIAudioSessionEnumerator
    If $__oIAudioSessionManager2.GetSessionEnumerator($pIAudioSessionEnumerator) < 0 Then Return
    $oIAudioSessionEnumerator = ObjCreateInterface($pIAudioSessionEnumerator, $sIID_IAudioSessionEnumerator, $sTagIAudioSessionEnumerator)
    If Not IsObj($oIAudioSessionEnumerator) Then Return SetError(1)

    Local $i, $nSessions, $pIAudioSessionControl2, $oIAudioSessionControl2
    Local $ProcessID, $oISimpleAudioVolume
    Local $bMute = 0, $error = 1
    If $oIAudioSessionEnumerator.GetCount($nSessions) >= 0 Then
        For $i = 0 To $nSessions - 1
            If $oIAudioSessionEnumerator.GetSession($i, $pIAudioSessionControl2) >= 0 Then
                $oIAudioSessionControl2 = ObjCreateInterface($pIAudioSessionControl2, $sIID_IAudioSessionControl2, $sTagIAudioSessionControl2)
                If @error Then ContinueLoop
                $oIAudioSessionControl2.GetProcessId($ProcessID)
                If $ProcessID = $pid Then
                    $oISimpleAudioVolume = ObjCreateInterface($pIAudioSessionControl2, $sIID_ISimpleAudioVolume, $sTagISimpleAudioVolume)
                    If @error Then ContinueLoop
                    $oIAudioSessionControl2.AddRef() ;stabilize
                    If $oISimpleAudioVolume.SetMasterVolume($value, 0) >= 0 Then
                        $error = 0
                        ExitLoop
                    EndIf
                EndIf
            EndIf
        Next
    EndIf
    $oISimpleAudioVolume = 0
    $oIAudioSessionControl2 = 0
    $oIAudioSessionEnumerator = 0
    ;MsgBox(0, $error, "App muted: " & $bMute)
    Return SetError($error, 0, $bMute)
EndFunc   ;==>Audio_SetMasterVolume

Func Audio_GetMasterVolume($pid)
    If Not IsObj($__oIAudioSessionManager2) Then
        $__oIAudioSessionManager2 = Audio_GetIAudioSessionManager2()
    EndIf
    If Not IsObj($__oIAudioSessionManager2) Then Return

    Local $pIAudioSessionEnumerator, $oIAudioSessionEnumerator
    If $__oIAudioSessionManager2.GetSessionEnumerator($pIAudioSessionEnumerator) < 0 Then Return
    $oIAudioSessionEnumerator = ObjCreateInterface($pIAudioSessionEnumerator, $sIID_IAudioSessionEnumerator, $sTagIAudioSessionEnumerator)
    If Not IsObj($oIAudioSessionEnumerator) Then Return SetError(1)

    Local $i, $nSessions, $pIAudioSessionControl2, $oIAudioSessionControl2
    Local $ProcessID, $oISimpleAudioVolume
    Local $bMute = 0, $error = 1
    If $oIAudioSessionEnumerator.GetCount($nSessions) >= 0 Then
        For $i = 0 To $nSessions - 1
            If $oIAudioSessionEnumerator.GetSession($i, $pIAudioSessionControl2) >= 0 Then
                $oIAudioSessionControl2 = ObjCreateInterface($pIAudioSessionControl2, $sIID_IAudioSessionControl2, $sTagIAudioSessionControl2)
                If @error Then ContinueLoop
                $oIAudioSessionControl2.GetProcessId($ProcessID)
                If $ProcessID = $pid Then
                    $oISimpleAudioVolume = ObjCreateInterface($pIAudioSessionControl2, $sIID_ISimpleAudioVolume, $sTagISimpleAudioVolume)
                    If @error Then ContinueLoop
                    $oIAudioSessionControl2.AddRef() ;stabilize
                    If $oISimpleAudioVolume.GetMasterVolume($bMute) >= 0 Then
                        $error = 0
                        ExitLoop
                    EndIf
                EndIf
            EndIf
        Next
    EndIf
    $oISimpleAudioVolume = 0
    $oIAudioSessionControl2 = 0
    $oIAudioSessionEnumerator = 0
    ;MsgBox(0, $error, "App muted: " & $bMute)
    Return SetError($error, 0, $bMute)
EndFunc   ;==>Audio_GetMasterVolume

Func Audio_GetIAudioSessionManager2()
    Local $oIAudioSessionManager2 = 0
    Local Const $eMultimedia = 1, $CLSCTX_INPROC_SERVER = 0x01
    Local $pIMMDevice, $oMMDevice, $pIAudioSessionManager2
    Local $oMMDeviceEnumerator = ObjCreateInterface($sCLSID_MMDeviceEnumerator, $sIID_IMMDeviceEnumerator, $sTagIMMDeviceEnumerator)
    If IsObj($oMMDeviceEnumerator) Then
        If $oMMDeviceEnumerator.GetDefaultAudioEndpoint(0, $eMultimedia, $pIMMDevice) >= 0 Then
            $oMMDevice = ObjCreateInterface($pIMMDevice, $sIID_IMMDevice, $sTagIMMDevice)
            If IsObj($oMMDevice) Then
                If $oMMDevice.Activate(__uuidof($sIID_IAudioSessionManager2), $CLSCTX_INPROC_SERVER, 0, $pIAudioSessionManager2) >= 0 Then
                    $oIAudioSessionManager2 = ObjCreateInterface($pIAudioSessionManager2, $sIID_IAudioSessionManager2, $sTagIAudioSessionManager2)
                EndIf
                $oMMDevice = 0
            EndIf
        EndIf
        $oMMDeviceEnumerator = 0
    EndIf

    If IsObj($oIAudioSessionManager2) Then
        Return $oIAudioSessionManager2
    EndIf
EndFunc   ;==>Audio_GetIAudioSessionManager2

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 CLSIDFromString($sGUID)
    Local $tGUID = DllStructCreate("ulong Data1;ushort Data2;ushort Data3;byte Data4[8]")
    DllCall("ole32.dll", "long", "CLSIDFromString", "wstr", $sGUID, "struct*", $tGUID)
    Return $tGUID
EndFunc   ;==>CLSIDFromString

Had fun on it so I inserted a fading and it's actually a random value :D

I don't know why but actually SoundSetWaveVolume() doesn't work... So i have to set the Master Volume up to 100 because the device volume compare to it :/

If you want it like the  SoundSetWaveVolume() just make a func of it with $soundAPP and $newValue as Parameter and delete that like the msgbox.

Edited by Aelc

why do i get garbage when i buy garbage bags? <_<

Link to comment
Share on other sites

I use MixerGetSet.au3 to control the sound of various pc devices.

$asComponentTypes[0] = "dUndefined"
$asComponentTypes[1] = "dDigital"
$asComponentTypes[2] = "dLine"
$asComponentTypes[3] = "dMonitor"
$asComponentTypes[4] = "dSpeakers"
$asComponentTypes[5] = "dHeadphones"
$asComponentTypes[6] = "dTelephone"
$asComponentTypes[7] = "dWave"
$asComponentTypes[8] = "dVoice"
$asComponentTypes[9] = "sUndefined"
$asComponentTypes[10] = "sDigital"
$asComponentTypes[11] = "sLine"
$asComponentTypes[12] = "sMicrophone"
$asComponentTypes[13] = "sSynthesizer"
$asComponentTypes[14] = "sCompactDisc"
$asComponentTypes[15] = "sTelephone"
$asComponentTypes[16] = "sPCSpeaker"
$asComponentTypes[17] = "sWave"
$asComponentTypes[18] = "sAuxiliary"
$asComponentTypes[19] = "sAnalog"
#include <GUIConstants.au3>

Const $MCA_WMID = 1
Const $MCA_WPID = 2
Const $MCA_VDRIVERVERSION = 3
Const $MCA_SZPNAME = 4
Const $MCA_FDWSUPPORT = 5
Const $MCA_CDESTINATIONS = 6
Const $MCA_STRUCT_DEF = "ushort;ushort;uint;char[32];dword;dword"
Const $ML_CBSTRUCT = 1
Const $ML_DWDESTINATION = 2
Const $ML_DWSOURCE = 3
Const $ML_DWLINEID = 4
Const $ML_FDWLINE = 5
Const $ML_DWUSER = 6
Const $ML_DWCOMPONENTTYPE = 7
Const $ML_CCHANNELS = 8
Const $ML_CCONNECTIONS = 9
Const $ML_CCONTROLS = 10
Const $ML_SZSHORTNAME = 11
Const $ML_SZNAME = 12
Const $ML_DWTYPE = 13
Const $ML_DWDEVICEID = 14
Const $ML_WMID = 15
Const $ML_WPID = 16
Const $ML_VDRIVERVERSION = 17
Const $ML_SZPNAME = 18
Const $ML_STRUCT_DEF = "dword;dword;dword;dword;dword;dword;dword;dword;dword;dword;char[16];char[64];dword;dword;ushort;ushort;uint;char[32]"
Const $MCO_CBSTRUCT = 1
Const $MCO_DWCONTROLID = 2
Const $MCO_DWCONTROLTYPE = 3
Const $MCO_FDWCONTROL = 4
Const $MCO_CMULTIPLEITEMS = 5
Const $MCO_SZSHORTNAME = 6
Const $MCO_SZNAME = 7
Const $MCO_LMINIMUM = 8
Const $MCO_LMAXIMUM = 9
Const $MCO_DWMINIMUM = 8
Const $MCO_DWMAXIMUM = 9
Const $MCO_DWRESERVED_1 = 10
Const $MCO_CSTEPS = 11
Const $MCO_CBCUSTOMDATA = 11
Const $MCO_DWRESERVED_2 = 12
Const $MCO_STRUCT_DEF = "dword;dword;dword;dword;dword;char[16];char[64];dword;dword;dword[4];dword;dword[5]"
Const $MLC_CBSTRUCT = 1
Const $MLC_DWLINEID = 2
Const $MLC_DWCONTROLID = 3
Const $MLC_DWCONTROLTYPE = 3
Const $MLC_CCONTROLS = 4
Const $MLC_CBMXCTRL = 5
Const $MLC_PAMXCTRL = 6
Const $MLC_STRUCT_DEF = "dword;dword;dword;dword;dword;ptr"
Const $MCD_CBSTRUCT = 1
Const $MCD_DWCONTROLID = 2
Const $MCD_CCHANNELS = 3
Const $MCD_HWNDOWNER = 4
Const $MCD_CMULTIPLEITEMS = 4
Const $MCD_CBDETAILS = 5
Const $MCD_PADETAILS = 6
Const $MCD_STRUCT_DEF = "dword;dword;dword;dword;dword;ptr"
Const $MCDU_DWVALUE = 1
Const $MCDU_STRUCT_DEF = "dword"

Const $MIXERLINE_COMPONENTTYPE_DST_FIRST = 0x00000000
Const $MIXERLINE_COMPONENTTYPE_DST_UNDEFINED = $MIXERLINE_COMPONENTTYPE_DST_FIRST + 0
Const $MIXERLINE_COMPONENTTYPE_DST_DIGITAL = $MIXERLINE_COMPONENTTYPE_DST_FIRST + 1
Const $MIXERLINE_COMPONENTTYPE_DST_LINE = $MIXERLINE_COMPONENTTYPE_DST_FIRST + 2
Const $MIXERLINE_COMPONENTTYPE_DST_MONITOR = $MIXERLINE_COMPONENTTYPE_DST_FIRST + 3
Const $MIXERLINE_COMPONENTTYPE_DST_SPEAKERS = $MIXERLINE_COMPONENTTYPE_DST_FIRST + 4
Const $MIXERLINE_COMPONENTTYPE_DST_HEADPHONES = $MIXERLINE_COMPONENTTYPE_DST_FIRST + 5
Const $MIXERLINE_COMPONENTTYPE_DST_TELEPHONE = $MIXERLINE_COMPONENTTYPE_DST_FIRST + 6
Const $MIXERLINE_COMPONENTTYPE_DST_WAVEIN = $MIXERLINE_COMPONENTTYPE_DST_FIRST + 7
Const $MIXERLINE_COMPONENTTYPE_DST_VOICEIN = $MIXERLINE_COMPONENTTYPE_DST_FIRST + 8
Const $MIXERLINE_COMPONENTTYPE_DST_LAST = $MIXERLINE_COMPONENTTYPE_DST_FIRST + 8
Const $MIXERLINE_COMPONENTTYPE_SRC_FIRST = 0x00001000
Const $MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED = $MIXERLINE_COMPONENTTYPE_SRC_FIRST + 0
Const $MIXERLINE_COMPONENTTYPE_SRC_DIGITAL = $MIXERLINE_COMPONENTTYPE_SRC_FIRST + 1
Const $MIXERLINE_COMPONENTTYPE_SRC_LINE = $MIXERLINE_COMPONENTTYPE_SRC_FIRST + 2
Const $MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE = $MIXERLINE_COMPONENTTYPE_SRC_FIRST + 3
Const $MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER = $MIXERLINE_COMPONENTTYPE_SRC_FIRST + 4
Const $MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC = $MIXERLINE_COMPONENTTYPE_SRC_FIRST + 5
Const $MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE = $MIXERLINE_COMPONENTTYPE_SRC_FIRST + 6
Const $MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER = $MIXERLINE_COMPONENTTYPE_SRC_FIRST + 7
Const $MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT = $MIXERLINE_COMPONENTTYPE_SRC_FIRST + 8
Const $MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY = $MIXERLINE_COMPONENTTYPE_SRC_FIRST + 9
Const $MIXERLINE_COMPONENTTYPE_SRC_ANALOG = $MIXERLINE_COMPONENTTYPE_SRC_FIRST + 10
Const $MIXERLINE_COMPONENTTYPE_SRC_LAST = $MIXERLINE_COMPONENTTYPE_SRC_FIRST + 10

Global $aiComponentTypes[20]
Global $asComponentTypes[20]

$aiComponentTypes[0] = $MIXERLINE_COMPONENTTYPE_DST_UNDEFINED
$aiComponentTypes[1] = $MIXERLINE_COMPONENTTYPE_DST_DIGITAL
$aiComponentTypes[2] = $MIXERLINE_COMPONENTTYPE_DST_LINE
$aiComponentTypes[3] = $MIXERLINE_COMPONENTTYPE_DST_MONITOR
$aiComponentTypes[4] = $MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
$aiComponentTypes[5] = $MIXERLINE_COMPONENTTYPE_DST_HEADPHONES
$aiComponentTypes[6] = $MIXERLINE_COMPONENTTYPE_DST_TELEPHONE
$aiComponentTypes[7] = $MIXERLINE_COMPONENTTYPE_DST_WAVEIN
$aiComponentTypes[8] = $MIXERLINE_COMPONENTTYPE_DST_VOICEIN
$aiComponentTypes[9] = $MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED
$aiComponentTypes[10] = $MIXERLINE_COMPONENTTYPE_SRC_DIGITAL
$aiComponentTypes[11] = $MIXERLINE_COMPONENTTYPE_SRC_LINE
$aiComponentTypes[12] = $MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE
$aiComponentTypes[13] = $MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER
$aiComponentTypes[14] = $MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC
$aiComponentTypes[15] = $MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE
$aiComponentTypes[16] = $MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER
$aiComponentTypes[17] = $MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT
$aiComponentTypes[18] = $MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY
$aiComponentTypes[19] = $MIXERLINE_COMPONENTTYPE_SRC_ANALOG

$asComponentTypes[0] = "dUndefined"
$asComponentTypes[1] = "dDigital"
$asComponentTypes[2] = "dLine"
$asComponentTypes[3] = "dMonitor"
$asComponentTypes[4] = "dSpeakers"
$asComponentTypes[5] = "dHeadphones"
$asComponentTypes[6] = "dTelephone"
$asComponentTypes[7] = "dWave"
$asComponentTypes[8] = "dVoice"
$asComponentTypes[9] = "sUndefined"
$asComponentTypes[10] = "sDigital"
$asComponentTypes[11] = "sLine"
$asComponentTypes[12] = "sMicrophone"
$asComponentTypes[13] = "sSynthesizer"
$asComponentTypes[14] = "sCompactDisc"
$asComponentTypes[15] = "sTelephone"
$asComponentTypes[16] = "sPCSpeaker"
$asComponentTypes[17] = "sWave"
$asComponentTypes[18] = "sAuxiliary"
$asComponentTypes[19] = "sAnalog"

Const $MIXERCONTROL_CT_CLASS_CUSTOM = 0x00000000
Const $MIXERCONTROL_CT_CLASS_METER = 0x10000000
Const $MIXERCONTROL_CT_CLASS_SWITCH = 0x20000000
Const $MIXERCONTROL_CT_CLASS_NUMBER = 0x30000000
Const $MIXERCONTROL_CT_CLASS_SLIDER = 0x40000000
Const $MIXERCONTROL_CT_CLASS_FADER = 0x50000000
Const $MIXERCONTROL_CT_CLASS_TIME = 0x60000000
Const $MIXERCONTROL_CT_CLASS_LIST = 0x70000000

Const $MIXERCONTROL_CT_SC_SWITCH_BOOLEAN = 0x00000000
Const $MIXERCONTROL_CT_SC_SWITCH_BUTTON = 0x01000000

Const $MIXERCONTROL_CT_SC_METER_POLLED = 0x00000000

Const $MIXERCONTROL_CT_SC_TIME_MICROSECS = 0x00000000
Const $MIXERCONTROL_CT_SC_TIME_MILLISECS = 0x01000000

Const $MIXERCONTROL_CT_SC_LIST_SINGLE = 0x00000000
Const $MIXERCONTROL_CT_SC_LIST_MULTIPLE = 0x01000000

Const $MIXERCONTROL_CT_UNITS_CUSTOM = 0x00000000
Const $MIXERCONTROL_CT_UNITS_BOOLEAN = 0x00010000
Const $MIXERCONTROL_CT_UNITS_SIGNED = 0x00020000
Const $MIXERCONTROL_CT_UNITS_UNSIGNED = 0x00030000
Const $MIXERCONTROL_CT_UNITS_DECIBELS = 0x00040000
Const $MIXERCONTROL_CT_UNITS_PERCENT = 0x00050000

Const $MIXERCONTROL_CONTROLTYPE_CUSTOM = BitOR($MIXERCONTROL_CT_CLASS_CUSTOM, $MIXERCONTROL_CT_UNITS_CUSTOM)
Const $MIXERCONTROL_CONTROLTYPE_BOOLEANMETER = BitOR($MIXERCONTROL_CT_CLASS_METER, $MIXERCONTROL_CT_SC_METER_POLLED, $MIXERCONTROL_CT_UNITS_BOOLEAN)
Const $MIXERCONTROL_CONTROLTYPE_SIGNEDMETER = BitOR($MIXERCONTROL_CT_CLASS_METER, $MIXERCONTROL_CT_SC_METER_POLLED, $MIXERCONTROL_CT_UNITS_SIGNED)
Const $MIXERCONTROL_CONTROLTYPE_PEAKMETER = $MIXERCONTROL_CONTROLTYPE_SIGNEDMETER + 1
Const $MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER = BitOR($MIXERCONTROL_CT_CLASS_METER, $MIXERCONTROL_CT_SC_METER_POLLED, $MIXERCONTROL_CT_UNITS_UNSIGNED)
Const $MIXERCONTROL_CONTROLTYPE_BOOLEAN = BitOR($MIXERCONTROL_CT_CLASS_SWITCH, $MIXERCONTROL_CT_SC_SWITCH_BOOLEAN, $MIXERCONTROL_CT_UNITS_BOOLEAN)
Const $MIXERCONTROL_CONTROLTYPE_ONOFF = $MIXERCONTROL_CONTROLTYPE_BOOLEAN + 1
Const $MIXERCONTROL_CONTROLTYPE_MUTE = $MIXERCONTROL_CONTROLTYPE_BOOLEAN + 2
Const $MIXERCONTROL_CONTROLTYPE_MONO = $MIXERCONTROL_CONTROLTYPE_BOOLEAN + 3
Const $MIXERCONTROL_CONTROLTYPE_LOUDNESS = $MIXERCONTROL_CONTROLTYPE_BOOLEAN + 4
Const $MIXERCONTROL_CONTROLTYPE_STEREOENH = $MIXERCONTROL_CONTROLTYPE_BOOLEAN + 5
Const $MIXERCONTROL_CONTROLTYPE_BUTTON = BitOR($MIXERCONTROL_CT_CLASS_SWITCH, $MIXERCONTROL_CT_SC_SWITCH_BUTTON, $MIXERCONTROL_CT_UNITS_BOOLEAN)
Const $MIXERCONTROL_CONTROLTYPE_DECIBELS = BitOR($MIXERCONTROL_CT_CLASS_NUMBER, $MIXERCONTROL_CT_UNITS_DECIBELS)
Const $MIXERCONTROL_CONTROLTYPE_SIGNED = BitOR($MIXERCONTROL_CT_CLASS_NUMBER, $MIXERCONTROL_CT_UNITS_SIGNED)
Const $MIXERCONTROL_CONTROLTYPE_UNSIGNED = BitOR($MIXERCONTROL_CT_CLASS_NUMBER, $MIXERCONTROL_CT_UNITS_UNSIGNED)
Const $MIXERCONTROL_CONTROLTYPE_PERCENT = BitOR($MIXERCONTROL_CT_CLASS_NUMBER, $MIXERCONTROL_CT_UNITS_PERCENT)
Const $MIXERCONTROL_CONTROLTYPE_SLIDER = BitOR($MIXERCONTROL_CT_CLASS_SLIDER, $MIXERCONTROL_CT_UNITS_SIGNED)
Const $MIXERCONTROL_CONTROLTYPE_PAN = $MIXERCONTROL_CONTROLTYPE_SLIDER + 1
Const $MIXERCONTROL_CONTROLTYPE_QSOUNDPAN = $MIXERCONTROL_CONTROLTYPE_SLIDER + 2
Const $MIXERCONTROL_CONTROLTYPE_FADER = BitOR($MIXERCONTROL_CT_CLASS_FADER, $MIXERCONTROL_CT_UNITS_UNSIGNED)
Const $MIXERCONTROL_CONTROLTYPE_VOLUME = $MIXERCONTROL_CONTROLTYPE_FADER + 1
Const $MIXERCONTROL_CONTROLTYPE_BASS = $MIXERCONTROL_CONTROLTYPE_FADER + 2
Const $MIXERCONTROL_CONTROLTYPE_TREBLE = $MIXERCONTROL_CONTROLTYPE_FADER + 3
Const $MIXERCONTROL_CONTROLTYPE_EQUALIZER = $MIXERCONTROL_CONTROLTYPE_FADER + 4
Const $MIXERCONTROL_CONTROLTYPE_SINGLESELECT = BitOR($MIXERCONTROL_CT_CLASS_LIST, $MIXERCONTROL_CT_SC_LIST_SINGLE, $MIXERCONTROL_CT_UNITS_BOOLEAN)
Const $MIXERCONTROL_CONTROLTYPE_MUX = $MIXERCONTROL_CONTROLTYPE_SINGLESELECT + 1
Const $MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT = BitOR($MIXERCONTROL_CT_CLASS_LIST, $MIXERCONTROL_CT_SC_LIST_MULTIPLE, $MIXERCONTROL_CT_UNITS_BOOLEAN)
Const $MIXERCONTROL_CONTROLTYPE_MIXER = $MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT + 1
Const $MIXERCONTROL_CONTROLTYPE_MICROTIME = BitOR($MIXERCONTROL_CT_CLASS_TIME, $MIXERCONTROL_CT_SC_TIME_MICROSECS, $MIXERCONTROL_CT_UNITS_UNSIGNED)
Const $MIXERCONTROL_CONTROLTYPE_MILLITIME = BitOR($MIXERCONTROL_CT_CLASS_TIME, $MIXERCONTROL_CT_SC_TIME_MILLISECS, $MIXERCONTROL_CT_UNITS_UNSIGNED)

Global $aiControlTypes[30]
Global $asControlTypes[30]

$aiControlTypes[0] = $MIXERCONTROL_CONTROLTYPE_CUSTOM
$aiControlTypes[1] = $MIXERCONTROL_CONTROLTYPE_BOOLEANMETER
$aiControlTypes[2] = $MIXERCONTROL_CONTROLTYPE_SIGNEDMETER
$aiControlTypes[3] = $MIXERCONTROL_CONTROLTYPE_PEAKMETER
$aiControlTypes[4] = $MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER
$aiControlTypes[5] = $MIXERCONTROL_CONTROLTYPE_BOOLEAN
$aiControlTypes[6] = $MIXERCONTROL_CONTROLTYPE_ONOFF
$aiControlTypes[7] = $MIXERCONTROL_CONTROLTYPE_MUTE
$aiControlTypes[8] = $MIXERCONTROL_CONTROLTYPE_MONO
$aiControlTypes[9] = $MIXERCONTROL_CONTROLTYPE_LOUDNESS
$aiControlTypes[10] = $MIXERCONTROL_CONTROLTYPE_STEREOENH
$aiControlTypes[11] = $MIXERCONTROL_CONTROLTYPE_BUTTON
$aiControlTypes[12] = $MIXERCONTROL_CONTROLTYPE_DECIBELS
$aiControlTypes[13] = $MIXERCONTROL_CONTROLTYPE_SIGNED
$aiControlTypes[14] = $MIXERCONTROL_CONTROLTYPE_UNSIGNED
$aiControlTypes[15] = $MIXERCONTROL_CONTROLTYPE_PERCENT
$aiControlTypes[16] = $MIXERCONTROL_CONTROLTYPE_SLIDER
$aiControlTypes[17] = $MIXERCONTROL_CONTROLTYPE_PAN
$aiControlTypes[18] = $MIXERCONTROL_CONTROLTYPE_QSOUNDPAN
$aiControlTypes[19] = $MIXERCONTROL_CONTROLTYPE_FADER
$aiControlTypes[20] = $MIXERCONTROL_CONTROLTYPE_VOLUME
$aiControlTypes[21] = $MIXERCONTROL_CONTROLTYPE_BASS
$aiControlTypes[22] = $MIXERCONTROL_CONTROLTYPE_TREBLE
$aiControlTypes[23] = $MIXERCONTROL_CONTROLTYPE_EQUALIZER
$aiControlTypes[24] = $MIXERCONTROL_CONTROLTYPE_SINGLESELECT
$aiControlTypes[25] = $MIXERCONTROL_CONTROLTYPE_MUX
$aiControlTypes[26] = $MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT
$aiControlTypes[27] = $MIXERCONTROL_CONTROLTYPE_MIXER
$aiControlTypes[28] = $MIXERCONTROL_CONTROLTYPE_MICROTIME
$aiControlTypes[29] = $MIXERCONTROL_CONTROLTYPE_MILLITIME

$asControlTypes[0] = "Custom"
$asControlTypes[1] = "BooleanMeter"
$asControlTypes[2] = "SignedMeter"
$asControlTypes[3] = "PeakMeter"
$asControlTypes[4] = "UnsignedMeter"
$asControlTypes[5] = "Boolean"
$asControlTypes[6] = "OnOff"
$asControlTypes[7] = "Mute"
$asControlTypes[8] = "Mono"
$asControlTypes[9] = "Loudness"
$asControlTypes[10] = "StereoEnh"
$asControlTypes[11] = "Button"
$asControlTypes[12] = "Decibels"
$asControlTypes[13] = "Signed"
$asControlTypes[14] = "Unsigned"
$asControlTypes[15] = "Percent"
$asControlTypes[16] = "Slider"
$asControlTypes[17] = "Pan"
$asControlTypes[18] = "QSoundPan"
$asControlTypes[19] = "Fader"
$asControlTypes[20] = "Volume"
$asControlTypes[21] = "Bass"
$asControlTypes[22] = "Treble"
$asControlTypes[23] = "Equalizer"
$asControlTypes[24] = "SingleSelect"
$asControlTypes[25] = "Mux"
$asControlTypes[26] = "MultipleSelect"
$asControlTypes[27] = "Mixer"
$asControlTypes[28] = "Microtime"
$asControlTypes[29] = "Millitime"

Const $MIXER_GETLINEINFOF_DESTINATION = 0x00000000
Const $MIXER_GETLINEINFOF_SOURCE = 0x00000001
Const $MIXER_GETLINEINFOF_LINEID = 0x00000002
Const $MIXER_GETLINEINFOF_COMPONENTTYPE = 0x00000003
Const $MIXER_GETLINEINFOF_TARGETTYPE = 0x00000004

Const $MIXER_GETLINECONTROLSF_ALL = 0x00000000
Const $MIXER_GETLINECONTROLSF_ONEBYID = 0x00000001
Const $MIXER_GETLINECONTROLSF_ONEBYTYPE = 0x00000002

Const $MIXER_GETCONTROLDETAILSF_VALUE = 0x00000000
Const $MIXER_GETCONTROLDETAILSF_LISTTEXT = 0x00000001

Const $MIXER_SETCONTROLDETAILSF_VALUE = 0x00000000
Const $MIXER_SETCONTROLDETAILSF_CUSTOM = 0x00000001

; ================================================================================= EXEMPLO
_MixerSet("dSpeakers", "volume", 0); <======== Baixa os alto falantes
Sleep(1000)
_MixerSet("dSpeakers", "volume", 100); <======== Aumenta os alto falantes
Sleep(1000)
_MixerSet("sWave", "volume", 0); <======== Baixa o som wave
Sleep(1000)
_MixerSet("sWave", "volume", 100); <======== Aumenta o som wave
; ================================================================================= EXEMPLO


;CÓDIGOS DE ERRO RETORNADOS

; 1 - ID do Mixer é inválido
; 2 - tipo de componente inválido
; 3 - instancia de componente invalida
; 4 - tipo de Controle inválido
; 5 - Não é possível abrir o Mixer especificado
; 6 - Mixer não suporta o componente especificado
; 7 - Mixer não tem o tipo de componente especificado
; 8 - componente não suporta o tipo de controle especificado
; 9 - Não é possível obter a configuração atual
; 10 - Não é possível alterar a configuração

;----------------------------------------------------------

;
; Nome:             _MixerGet
; Descrição:      Retorna o valor do controle solicitado
; Sintese           _MixerGet($sComponentType, $sControlType)
; Parametros:
;                   $sComponentType - Nome do componente
;
;                       - dUndefined
;                       - dDigital
;                       - dLine
;                       - dMonitor
;                       - dSpeakers
;                       - dHeadphones
;                       - dTelephone
;                       - dWave
;                       - dVoice
;                       - sUndefined
;                       - sDigital
;                       - sLine
;                       - sMicrophone
;                       - sSynthesizer
;                       - sCompactDisc
;                       - sTelephone
;                       - sPCSpeaker
;                       - sWave
;                       - sAuxiliary
;                       - sAnalog
;
;           $sControlType - Tipo de Controle
;
;                       - Custom
;                       - BooleanMeter
;                       - SignedMeter
;                       - PeakMeter
;                       - UnsignedMeter
;                       - Boolean
;                       - OnOff
;                       - Mute
;                       - Mono
;                       - Loudness
;                       - StereoEnh
;                       - Button
;                       - Decibels
;                       - Signed
;                       - Unsigned
;                       - Percent
;                       - Slider
;                       - Pan
;                       - QSoundPan
;                       - Fader
;                       - Volume
;                       - Bass
;                       - Treble
;                       - Equalizer
;                       - SingleSelect
;                       - Mux
;                       - MultipleSelect
;                       - Mixer
;                       - Microtime
;                       - Millitime
;
; Valor Retornado:    Sucesso - retorna @error = 0 e o valor do controle acessado
;                       caixa de seleção retorna 0 or 1.
;
;                   Falha - Retorna 0 e código do @error :
;
; 1 - ID do Mixer é inválido
; 2 - tipo de componente inválido
; 3 - instancia de componente invalida
; 4 - tipo de Controle inválido
; 5 - Não é possível abrir o Mixer especificado
; 6 - Mixer não suporta o componente especificado
; 7 - Mixer não tem o tipo de componente especificado
; 8 - componente não suporta o tipo de controle especificado
; 9 - Não é possível obter a configuração atual
; 10 - Não é possível alterar a configuração
;
;
;
;-------------------------------------------------------------
Func _MixerGet($sComponentType, $sControlType)
    $iMixerID = 0
    $iComponentInstance = 1
    Local $iRet = MixerSetGet($iMixerID, $sComponentType, $iComponentInstance, $sControlType, False, 0)
    SetError(@error)
    Return $iRet
EndFunc   ;==>_MixerGet

;----------------------------
;
; Nome:        _MixerSet
; Descrição:      Grava o valor no controle especificado
;
; Síntese:      _MixerSet($sComponentType, $sControlType, $iNewParamValue)
;
; Parametros:   $sComponentType = Nome do componente   (os mesmos da lista de _MixerGet)
;
;               $sControlType - Tipo de Controle (os mesmos da lista de _MixerGet)
;
;
;
;   $iNewParamValue = Novo valor
;                   Para controles (caixa de seleção) zero é igual Off e 1 é igual On.
;                   Para outros controles este é um percentual de 0 a 100
;
; Valores Retornados:   Successo Retorna @error = 0 e o valor fixado no controle
;
;                   Falha - Retorna 0 e código do @error (os mesmos da lista de _MixerGet)
;
;-----------------------------------------------------------------------------------------------
Func _MixerSet($sComponentType, $sControlType, $iNewParamValue)
    $iMixerID = 0
    $iComponentInstance = 1
    Local $iRet = MixerSetGet($iMixerID, $sComponentType, $iComponentInstance, $sControlType, True, $iNewParamValue)
    SetError(@error)
    Return $iRet
EndFunc   ;==>_MixerSet


; Funções Internas

Func MixerOpen(ByRef $hMixer, $iMixerID, $hCallback, $iInstance, $iFlags)
    Local $hStruct = DllStructCreate("ptr")
    Local $iRet = DllCall("winmm.dll", "uint", "mixerOpen", "ptr", DllStructGetPtr($hStruct), "uint", $iMixerID, "dword", $hCallback, "dword", $iInstance, "dword", $iFlags)
    If @error Or $iRet[0] Then
        Return False
    Else
        $hMixer = DllStructGetData($hStruct, 1)
        Return True
    EndIf
EndFunc   ;==>MixerOpen

Func MixerClose($hMixer)
    Local $iRet = DllCall("winmm.dll", "uint", "mixerClose", "uint", $hMixer)
    If @error Or $iRet[0] Then
        Return False
    Else
        Return True
    EndIf
EndFunc   ;==>MixerClose

Func MixerGetDevCaps($hMixer, ByRef $hMxCaps)
    Local $iRet = DllCall("winmm.dll", "uint", "mixerGetDevCaps", "uint", $hMixer, "ptr", DllStructGetPtr($hMxCaps), "uint", DllStructGetSize($hMxCaps))
    If @error Or $iRet[0] Then
        Return False
    Else
        Return True
    EndIf
EndFunc   ;==>MixerGetDevCaps

Func MixerGetLineInfo($hMixer, ByRef $hMxLine, $iFlags)
    DllStructSetData($hMxLine, $ML_CBSTRUCT, DllStructGetSize($hMxLine))
    Local $iRet = DllCall("winmm.dll", "uint", "mixerGetLineInfo", "uint", $hMixer, "ptr", DllStructGetPtr($hMxLine), "dword", $iFlags)
    If @error Or $iRet[0] Then
        Return False
    Else
        Return True
    EndIf
EndFunc   ;==>MixerGetLineInfo

Func MixerGetLineControls($hMixer, ByRef $hMxLineCtrls, $iFlags)
    DllStructSetData($hMxLineCtrls, $MLC_CBSTRUCT, DllStructGetSize($hMxLineCtrls))
    Local $iRet = DllCall("winmm.dll", "uint", "mixerGetLineControls", "uint", $hMixer, "ptr", DllStructGetPtr($hMxLineCtrls), "dword", $iFlags)
    If @error Or $iRet[0] Then
        Return False
    Else
        Return True
    EndIf
EndFunc   ;==>MixerGetLineControls

Func MixerGetControlDetails($hMixer, ByRef $hMxCtrlDetails, $iFlags)
    DllStructSetData($hMxCtrlDetails, $MCD_CBSTRUCT, DllStructGetSize($hMxCtrlDetails))
    Local $iRet = DllCall("winmm.dll", "uint", "mixerGetControlDetails", "uint", $hMixer, "ptr", DllStructGetPtr($hMxCtrlDetails), "dword", $iFlags)
    If @error Or $iRet[0] Then
        Return False
    Else
        Return True
    EndIf
EndFunc   ;==>MixerGetControlDetails

Func MixerSetControlDetails($hMixer, ByRef $hMxCtrlDetails, $iFlags)
    DllStructSetData($hMxCtrlDetails, $MCD_CBSTRUCT, DllStructGetSize($hMxCtrlDetails))
    Local $iRet = DllCall("winmm.dll", "uint", "mixerSetControlDetails", "uint", $hMixer, "ptr", DllStructGetPtr($hMxCtrlDetails), "dword", $iFlags)
    If @error Or $iRet[0] Then
        Return False
    Else
        Return True
    EndIf
EndFunc   ;==>MixerSetControlDetails


Func MixerSetGet($iMixerID, $sComponentType, $iComponentInstance, $sControlType, $fIsSet, $iNewParamValue)

    ;verifica Id
    If Not IsInt($iMixerID) Or $iMixerID < 0 Then
        SetError(1)
        Return 0
    EndIf

    ;determina o tipo de componente
    Local $iComponentType = -1
    For $iIndex = 0 To UBound($asComponentTypes) - 1
        If StringCompare($sComponentType, $asComponentTypes[$iIndex]) = 0 Then
            $iComponentType = $aiComponentTypes[$iIndex]
            ExitLoop
        EndIf
    Next

    ; verifica tipo de componente
    If $iComponentType = -1 Then
        SetError(2)
        Return 0
    EndIf

    ; verifica instância do componente
    If Not IsInt($iComponentInstance) Or $iComponentInstance <= 0 Then
        SetError(3)
        Return 0
    EndIf

    ; Determina o tipo de controle
    Local $iControlType = -1
    For $iIndex = 0 To UBound($asControlTypes) - 1
        If StringCompare($sControlType, $asControlTypes[$iIndex]) = 0 Then
            $iControlType = $aiControlTypes[$iIndex]
            ExitLoop
        EndIf
    Next

    If $iControlType = -1 Then
        SetError(4)
        Return 0
    EndIf

    ;abre o Mixer especificado
    Local $hMixer
    If Not MixerOpen($hMixer, $iMixerID, 0, 0, 0) Then
        SetError(5)
        Return 0
    EndIf


    Local $iDestCount
    Local $hMxCaps = DllStructCreate($MCA_STRUCT_DEF)
    If MixerGetDevCaps($hMixer, $hMxCaps) Then
        $iDestCount = DllStructGetData($hMxCaps, $MCA_CDESTINATIONS)
    Else
        $iDestCount = 1
    EndIf


    Local $hMxLine = DllStructCreate($ML_STRUCT_DEF)
    If $iComponentInstance = 1 Then
        DllStructSetData($hMxLine, $ML_DWCOMPONENTTYPE, $iComponentType)
        If Not MixerGetLineInfo($hMixer, $hMxLine, $MIXER_GETLINEINFOF_COMPONENTTYPE) Then
            MixerClose($hMixer)
            SetError(6)
            Return 0
        EndIf
    Else

        Local $fFound = False
        Local $iCurDest = 0
        Local $iInstanceFound = 0
        While $iCurDest < $iDestCount And Not $fFound
            DllStructSetData($hMxLine, $ML_DWDESTINATION, $iCurDest)
            If Not MixerGetLineInfo($hMixer, $hMxLine, $MIXER_GETLINEINFOF_DESTINATION) Then
                $iCurDest = $iCurDest + 1
                ContinueLoop
            EndIf
            Local $iSrcCount = DllStructGetData($hMxLine, $ML_CCONNECTIONS)
            Local $iCurSrc = 0
            While $iCurSrc < $iSrcCount And Not $fFound
                DllStructSetData($hMxLine, $ML_DWDESTINATION, $iCurDest)
                DllStructSetData($hMxLine, $ML_DWSOURCE, $iCurSrc)
                If Not MixerGetLineInfo($hMixer, $hMxLine, $MIXER_GETLINEINFOF_SOURCE) Then
                    $iCurSrc = $iCurSrc + 1
                    ContinueLoop
                EndIf
                If DllStructGetData($hMxLine, $ML_DWCOMPONENTTYPE) = $iComponentType Then
                    $iInstanceFound = $iInstanceFound + 1
                    If $iInstanceFound = $iComponentInstance Then
                        $fFound = True
                    EndIf
                EndIf
                $iCurSrc = $iCurSrc + 1
            WEnd
            $iCurDest = $iCurDest + 1
        WEnd
        If Not $fFound Then
            MixerClose($hMixer)
            SetError(7)
            Return 0
        EndIf
    EndIf

    Local $hMxLineCtrls = DllStructCreate($MLC_STRUCT_DEF)
    Local $hMxCtrl = DllStructCreate($MCO_STRUCT_DEF)
    DllStructSetData($hMxLineCtrls, $MLC_CBSTRUCT, DllStructGetSize($hMxLineCtrls))
    DllStructSetData($hMxLineCtrls, $MLC_DWLINEID, DllStructGetData($hMxLine, $ML_DWLINEID))
    DllStructSetData($hMxLineCtrls, $MLC_DWCONTROLTYPE, $iControlType)
    DllStructSetData($hMxLineCtrls, $MLC_CCONTROLS, 1)
    DllStructSetData($hMxLineCtrls, $MLC_CBMXCTRL, DllStructGetSize($hMxCtrl))
    DllStructSetData($hMxLineCtrls, $MLC_PAMXCTRL, DllStructGetPtr($hMxCtrl))
    If Not MixerGetLineControls($hMixer, $hMxLineCtrls, $MIXER_GETLINECONTROLSF_ONEBYTYPE) Then
        MixerClose($hMixer)
        SetError(8)
        Return 0
    EndIf

    Local $iMin = DllStructGetData($hMxCtrl, $MCO_DWMINIMUM)
    Local $iMax = DllStructGetData($hMxCtrl, $MCO_DWMAXIMUM)

    Local $fControlTypeIsBoolean
    Switch $iControlType
        Case $MIXERCONTROL_CONTROLTYPE_ONOFF
            $fControlTypeIsBoolean = True
        Case $MIXERCONTROL_CONTROLTYPE_MUTE
            $fControlTypeIsBoolean = True
        Case $MIXERCONTROL_CONTROLTYPE_MONO
            $fControlTypeIsBoolean = True
        Case $MIXERCONTROL_CONTROLTYPE_LOUDNESS
            $fControlTypeIsBoolean = True
        Case $MIXERCONTROL_CONTROLTYPE_STEREOENH
            $fControlTypeIsBoolean = True
        Case Else
            $fControlTypeIsBoolean = False
    EndSwitch

    Local $fAdjustCurrentSettings = False
    If $fIsSet And (StringLeft($iNewParamValue, 1) = "+" Or StringLeft($iNewParamValue, 1) = "-") Then
        $fAdjustCurrentSettings = True
    EndIf


    Local $hMxCtrlDetails = DllStructCreate($MCD_STRUCT_DEF)
    Local $hMxCtrlValue = DllStructCreate($MCDU_STRUCT_DEF)
    DllStructSetData($hMxCtrlDetails, $MCD_CBSTRUCT, DllStructGetSize($hMxCtrlDetails))
    DllStructSetData($hMxCtrlDetails, $MCD_DWCONTROLID, DllStructGetData($hMxCtrl, $MCO_DWCONTROLID))
    DllStructSetData($hMxCtrlDetails, $MCD_CCHANNELS, 1)
    DllStructSetData($hMxCtrlDetails, $MCD_CBDETAILS, DllStructGetSize($hMxCtrlValue))
    DllStructSetData($hMxCtrlDetails, $MCD_PADETAILS, DllStructGetPtr($hMxCtrlValue))

    Local $iCurValue = 0
    If $fAdjustCurrentSettings Then
        If Not MixerGetControlDetails($hMixer, $hMxCtrlDetails, $MIXER_GETCONTROLDETAILSF_VALUE) Then
            MixerClose($hMixer)
            SetError(9)
            Return 0
        EndIf
        $iCurValue = DllStructGetData($hMxCtrlValue, $MCDU_DWVALUE)
    EndIf

    If $fIsSet Then
        If $fControlTypeIsBoolean Then
            If $fAdjustCurrentSettings Then
                If $iCurValue > $iMin Then
                    DllStructSetData($hMxCtrlValue, $MCDU_DWVALUE, $iMin)
                Else
                    DllStructSetData($hMxCtrlValue, $MCDU_DWVALUE, $iMax)
                EndIf
            Else
                If $iNewParamValue > 0 Then
                    DllStructSetData($hMxCtrlValue, $MCDU_DWVALUE, $iMax)
                Else
                    DllStructSetData($hMxCtrlValue, $MCDU_DWVALUE, $iMin)
                EndIf
            EndIf
        Else
            Local $iNewActualValue = ($iMax - $iMin) * ($iNewParamValue / 100.0)
            If $fAdjustCurrentSettings Then
                $iNewActualValue = $iNewActualValue + $iCurValue
            EndIf
            If $iNewActualValue < $iMin Then
                $iNewActualValue = $iMin
            ElseIf $iNewActualValue > $iMax Then
                $iNewActualValue = $iMax
            EndIf
            DllStructSetData($hMxCtrlValue, $MCDU_DWVALUE, $iNewActualValue)
        EndIf

        If Not MixerSetControlDetails($hMixer, $hMxCtrlDetails, $MIXER_SETCONTROLDETAILSF_VALUE) Then
            MixerClose($hMixer)
            SetError(10)
            Return 0
        EndIf
    EndIf

    If Not MixerGetControlDetails($hMixer, $hMxCtrlDetails, $MIXER_GETCONTROLDETAILSF_VALUE) Then
        MixerClose($hMixer)
        SetError(9)
        Return 0
    EndIf
    $iCurValue = DllStructGetData($hMxCtrlValue, $MCDU_DWVALUE)
    MixerClose($hMixer)
    SetError(0)

    If $fControlTypeIsBoolean Then
        If $iCurValue Then
            Return 1
        Else
            Return 0
        EndIf
    Else
        Return Round(100.0 * ($iCurValue - $iMin) / ($iMax - $iMin), 2)
    EndIf

EndFunc   ;==>MixerSetGet

Note: I no longer remember where I got it and I also don't know the author's name.

Link to comment
Share on other sites

Great - I got this working with your code Alec.

Thanks again for yours too Belini, however I was looking for something that could control sound for a specific process, ie. firefox.exe, etc. I couldn't find anything in your code for that, but maybe I missed it.

That said, I was looking for a way to toggle mute as well and just substituted:

$oISimpleAudioVolume.SetMasterVolume($value, 0)

for this:

$oISimpleAudioVolume.SetMute(True, 0) ;Enable mute
$oISimpleAudioVolume.SetMute(False, 0) ;Disable mute

...using the SetMute method for the ISimpleAudioVolume interface.

Many, many thanks!

Link to comment
Share on other sites

  • 1 year later...

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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...