sounddevice switcher für vista und win7

  • seit windows vista ist das handling mit den unterschiedlichen soundkarten etwas umständlich geraten.
    mich persönlich nervt das so ziemlich und ich suchte nach einer möglichkeit das mit weniger mausklicks zu bewerkstelligen.
    ich glaube ich habe es geschafft.

    mein script plaziert ein icon im tray und lässt diverse vorhandene sounddevices auswählen.
    leider ist das setzen der werte in der registry für mich nicht ganz so einfach zu verstehen, da an den wichtigen stellen mit hex werten gearbeitet wird.
    daher habe ich mich entschieden auf ein weiteres tool zurück zu greifen, was die werte setzt.
    es wird im archiv mitgeliefert


    Features:
    Auslesen der Namen der Sounddevices
    es werden dynamisch items für 2 bis 3 4 soundkarten gesetzt. (beliebig erweiterbar)
    ca 4 mb speicherverbrauch
    0% prozessorlast
    schnell im umschalten
    eine tolle blase die zeigt was gerade an ist ;)
    option zum deaktivieren der blase.
    das aktive gerät ist ausgegraut (leider erst nach dem ersten setzen)


    wünsche an euch:
    bugreports
    tips zur verbesserung geben
    im gesamten mithelfen das tool noch besser zu machen.


    hier nun das prachtstück:

    Spoiler anzeigen
    [autoit]

    #region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_Icon=1320412398_emblem-sound.ico
    #AutoIt3Wrapper_Outfile=soundchanger mit tray 1.0.exe
    #AutoIt3Wrapper_Compression=4
    #AutoIt3Wrapper_Res_Fileversion=1.0
    #AutoIt3Wrapper_Res_Language=1031
    #AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker
    #AutoIt3Wrapper_Run_Tidy=y
    #AutoIt3Wrapper_Run_Obfuscator=y
    #endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
    #include <Constants.au3>
    #include <Array.au3>
    Opt("TrayMenuMode", 3)

    [/autoit] [autoit][/autoit] [autoit]

    Local $reg[1]
    Local $devnamen[1]
    Local $blase = 1

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    If @CPUArch = "X64" Then ; wenn x64 dann nimm den 64er regschlüssel
    Global $key = "HKEY_LOCAL_MACHINE64\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render"
    Else
    Global $key = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render"
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To 20 ; bis zu 20 geräteschlüssel werden ausgelesen
    Local $var = RegEnumKey($key, $i)
    If @error <> 0 Then ExitLoop
    $devices = RegRead($key & "\" & $var, "DeviceState") ; status des gerätes (nutzbar?!?)
    If $devices = 1 Then ; wenn nutzbar dann steht da eine 1, also nimm das mit auf
    $devname = RegRead($key & "\" & $var & "\" & "Properties", "{b3f8fa53-0004-438e-9003-51a46e139bfc},6") ; name des gerätes
    _ArrayAdd($reg, $var) ; regschlüssel
    _ArrayAdd($devnamen, $devname) ; gerätenamen
    EndIf
    Next
    _ArrayDelete($devnamen, 0)
    _ArrayDelete($reg, 0)

    [/autoit] [autoit][/autoit] [autoit]

    $devs = UBound($devnamen)
    $hdmi = TrayCreateItem($devnamen[0])
    $real = TrayCreateItem($devnamen[1])
    If $devs > 2 Then $head = TrayCreateItem($devnamen[2])
    TrayCreateItem("")
    $noblase = TrayCreateItem("Kein Traytip")
    TrayCreateItem("")
    $exititem = TrayCreateItem("Beenden")

    [/autoit] [autoit][/autoit] [autoit]

    TraySetState()
    TraySetClick(1)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While 1
    $msg = TrayGetMsg()
    Select
    Case $msg = $hdmi
    Run("SetDefaultAudioDevice.exe" & " " & $reg[0] & " " & "communications", "", @SW_HIDE)
    Run("SetDefaultAudioDevice.exe" & " " & $reg[0] & " " & "multimedia", "", @SW_HIDE)
    If $blase = 1 Then TrayTip("Sounddevice", "" & $devnamen[0], 5, 1)
    TrayItemSetState($hdmi, $TRAY_DISABLE)
    TrayItemSetState($real, $TRAY_ENABLE)
    TrayItemSetState($head, $TRAY_ENABLE)
    Sleep(3000)
    Case $msg = $real
    Run("SetDefaultAudioDevice.exe" & " " & $reg[1] & " " & "communications", "", @SW_HIDE)
    Run("SetDefaultAudioDevice.exe" & " " & $reg[1] & " " & "multimedia", "", @SW_HIDE)
    If $blase = 1 Then TrayTip("Sounddevice", "" & $devnamen[1], 5, 1)
    TrayItemSetState($hdmi, $TRAY_ENABLE)
    TrayItemSetState($real, $TRAY_DISABLE)
    TrayItemSetState($head, $TRAY_ENABLE)
    Sleep(3000)
    EndSelect
    If $devs > 2 Then
    Select
    Case $msg = $head
    Run("SetDefaultAudioDevice.exe" & " " & $reg[2] & " " & "communications", "", @SW_HIDE)
    Run("SetDefaultAudioDevice.exe" & " " & $reg[2] & " " & "multimedia", "", @SW_HIDE)
    If $blase = 1 Then TrayTip("Sounddevice", "" & $devnamen[2], 5, 1)
    TrayItemSetState($hdmi, $TRAY_ENABLE)
    TrayItemSetState($real, $TRAY_ENABLE)
    TrayItemSetState($head, $TRAY_DISABLE)
    Sleep(3000)
    EndSelect
    EndIf
    Select
    Case $msg = $noblase
    If $blase = 1 Then
    $blase = 0
    Else
    $blase = 1
    TrayTip("", "Traytips werden wieder angezeigt", 5, 1)
    EndIf
    Case $msg = $exititem
    ExitLoop
    EndSelect
    WEnd

    [/autoit]

    Ich hoffe es ist für euch genauso nützlich wie für mich.


    Gruß

    Maximus1


    UPDATE:
    22.03.2012
    - Update durchgeführt und die maximale Anzahl auf 4 Geräte erhöht


    Die neue und zukünftige versionen könnt ihr auf meiner seite laden.
    maxtools... fast alle meine tools

  • Sehr schön. warum hat MS nur diese Funktionen nicht frei zugänglich gemacht :( Wenn du dich mit ObjCreateInterface und der undokumentierten API auseinandersetzen willst, dann kannst du das zusätzliche Programm ersetzen. Ausschnitt aus einem Skript von trancexx:

    Spoiler anzeigen
    [autoit]

    Global Const $sCLSID_CPolicyConfigClient = "{870af99c-171d-4f9e-af0d-e63df40c2bc9}"
    Global Const $sIID_IPolicyConfig = "{f8679f50-850a-41cf-9c72-430f290290c8}"

    [/autoit] [autoit][/autoit] [autoit]

    ; Author: trancexx
    Global Const $tagIPolicyConfig = "GetMixFormat hresult(wstr;ptr*);" & _
    "GetDeviceFormat hresult(wstr;int;ptr*);" & _
    "ResetDeviceFormat hresult(wstr);" & _
    "SetDeviceFormat hresult(wstr;ptr;ptr);" & _
    "GetProcessingPeriod hresult(wstr;int;int64*;int64*);" & _
    "SetProcessingPeriod hresult(wstr;int64*);" & _
    "GetShareMode hresult(wstr;ptr);" & _
    "SetShareMode hresult(wstr;ptr);" & _
    "GetPropertyValue hresult(wstr;struct;variant*);" & _
    "SetPropertyValue hresult(wstr;struct;variant*);" & _
    "SetDefaultEndpoint hresult(wstr;int);" & _
    "SetEndpointVisibility hresult(wstr;int);"

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $S_OK = 0

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $eConsole = 0
    Global Const $eMultimedia = 1
    Global Const $eCommunications = 2
    Global Const $ERole_enum_count = 3

    [/autoit] [autoit][/autoit] [autoit]

    Func _SwitchToDevice($sId)
    ; Author: trancexx
    Local $oPolicyConfig = ObjCreateInterface($sCLSID_CPolicyConfigClient, $sIID_IPolicyConfig, $tagIPolicyConfig)

    Local $hResult
    $hResult = $oPolicyConfig.SetDefaultEndpoint($sId, $eConsole)
    If $hResult = $S_OK Then $hResult = $oPolicyConfig.SetDefaultEndpoint($sId, $eCommunications)

    Return $hResult = $S_OK
    EndFunc ;==>_SwitchToDevice

    [/autoit]

    Warum erstellst du die TrayItems nicht in einer Schleife? Dadurch kannst du die Anzahl der Geräte beliebig halten.


  • Warum erstellst du die TrayItems nicht in einer Schleife? Dadurch kannst du die Anzahl der Geräte beliebig halten.


    Dann wühlt das Skript aber auch ständig in der Reg. rum!
    So oft wird ja kein neues Audiogerät hinzugefügt. 8)
    Eine Refresh Funktion könnte ein eigenes Tray-Item bekommen?


    Im Skript selbst wird die Device-Anzahl schon auf 20 beschänkt.
    Wieso dann nicht gleich das Array entsprechend deklarieren?
    _Arrayadd ist durch die Funktion "Redim" nicht so besonders schnell.
    In dem Fall machts wahrscheinlich aber gar nicht so viel aus.

  • Im Skript selbst wird die Device-Anzahl schon auf 20 beschänkt.
    Wieso dann nicht gleich das Array entsprechend deklarieren?


    Die Beschränkung auf 20 ist schon OK, wer hat schon 20 Geräte? Ich bezog mich jetzt auf Zeile 40+:

    [autoit]

    $hdmi = TrayCreateItem($devnamen[0])
    $real = TrayCreateItem($devnamen[1])
    If $devs > 2 Then $head = TrayCreateItem($devnamen[2])

    [/autoit]
  • das lässt sich ja auch beliebig erweitern. einfach für mehr devices

    [autoit]

    If $devs > XXXX Then $head = TrayCreateItem($devnamen[XXX])

    [/autoit]

    auswechseln.

    das gleiche muss dann aber auch in der while schleife passieren.
    desweiteren sollten die variablen für die geräte angepasst werden.

    [autoit]

    If $devs >XXX Then
    Select
    Case $msg = $head
    Run("SetDefaultAudioDevice.exe" & " " & $reg[XXX] & " " & "communications", "", @SW_HIDE)
    Run("SetDefaultAudioDevice.exe" & " " & $reg[XXX] & " " & "multimedia", "", @SW_HIDE)
    If $blase = 1 Then TrayTip("Sounddevice", "" & $devnamen[XXX], 5, 1)
    TrayItemSetState($hdmi, $TRAY_ENABLE)
    TrayItemSetState($real, $TRAY_ENABLE)
    TrayItemSetState($head, $TRAY_DISABLE)
    Sleep(3000)
    EndSelect
    EndIf

    [/autoit]


    zusätzlich noch was tolles einfallen lassen um die trayitems den dis- oder enablen.

    @ andi: ne ich glaube ich schlage mich erst mit der api oder anderem rum, wenn ich wirklich nicht mehr hinterrücks weiter komme. ich verbringe so schon mehr zeit mit googlen und testing als mit dem wirklichen schreiben.

    ich habe in der zwischenzeit die finger doch nicht ganz davon lassen können und per

    [autoit]


    FileInstall("SDAD.exe", @TempDir & "\")
    .
    .
    .
    .
    .
    Run(@TempDir & "\SDAD.exe" & " " & $reg[0] & " " & "communications", "", @SW_HIDE)
    Run(@TempDir & "\SDAD.exe" & " " & $reg[0] & " " & "multimedia", "", @SW_HIDE)

    [/autoit]


    sowie res add files im compiler alles zusammengepackt.

    I spent 10 minutes reviewing code and thinking "What kind of drugs is this guy on?" before realizing it was something I wrote.

    3 Mal editiert, zuletzt von Maximus1 (1. Februar 2012 um 15:48)

  • es gab ein kleines update


    UPDATE:
    22.03.2012
    - Update durchgeführt und die maximale Anzahl auf 4 Geräte erhöht

    I spent 10 minutes reviewing code and thinking "What kind of drugs is this guy on?" before realizing it was something I wrote.

  • ich brauche nochmal eure hilfe.
    ich habe wie viele andere mittlerweile probleme beim umschalten des sound devices und daher mal genauer geschaut wieso und weshalb.

    ich glaube ich habe es hinbekommen, aber jetzt dauert das umschalten ewigkeiten.

    kann mir jemand erklären warum?

    [autoit]


    #region ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_Icon=1320412398_emblem-sound.ico
    #AutoIt3Wrapper_Outfile=soundchanger mit tray test.exe
    #AutoIt3Wrapper_Res_Description=Einfaches Umschalten der Soundger�te unter Vista und Windows 7.
    #AutoIt3Wrapper_Res_Fileversion=1.1.0.0
    #AutoIt3Wrapper_Res_File_Add=SDAD.exe
    #endregion ;**** Directives created by AutoIt3Wrapper_GUI ****
    #include <Constants.au3>
    #include <Array.au3>
    Opt("TrayMenuMode", 3)

    [/autoit][autoit][/autoit][autoit]

    FileInstall("SDAD.exe", @TempDir & "")
    Local $reg[1]
    Local $devnamen[1]
    Local $devnamenalt[1]
    Local $blase = 1

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    If @CPUArch = "X64" Then ; wenn x64 dann nimm den 64er regschl�ssel
    Global $key = "HKEY_LOCAL_MACHINE64\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render"
    Else
    Global $key = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\MMDevices\Audio\Render"
    EndIf

    [/autoit][autoit][/autoit][autoit]

    For $i = 1 To 20
    Local $var = RegEnumKey($key, $i)
    If @error <> 0 Then ExitLoop
    $devices = RegRead($key & "" & $var, "DeviceState") ; status des ger�tes (nutzbar?!?)
    If $devices = 1 Then ; wenn nutzbar dann steht da eine 1, also nimm das mit auf
    $devname = RegRead($key & "" & $var & "" & "Properties", "{b3f8fa53-0004-438e-9003-51a46e139bfc},6") ; name des ger�tes
    $devname2 = RegRead($key & "" & $var & "" & "Properties", "{a45c254e-df1c-4efd-8020-67d146a850e0},2") ; alternativer name des ger�tes

    [/autoit][autoit][/autoit][autoit]

    _ArrayAdd($reg, $var) ; regschl�ssel
    _ArrayAdd($devnamen, $devname) ; ger�tenamen
    _ArrayAdd($devnamenalt, $devname2) ; ger�tenamen
    EndIf
    Next
    ;~ _ArrayDisplay($devnamen)
    _ArrayDelete($devnamen, 0)
    _ArrayDelete($reg, 0)
    _ArrayDelete($devnamenalt, 0)
    ;~ _ArrayDisplay($devnamenalt)

    [/autoit][autoit][/autoit][autoit][/autoit][autoit][/autoit][autoit]

    $devs = UBound($devnamen) - 1
    ;MsgBox(0, "", $devs)
    $dev0 = TrayCreateItem($devnamen[0]&" " & $devnamenalt[0])
    $dev1 = TrayCreateItem($devnamen[1]&" " & $devnamenalt[1])
    ;~ MsgBox(0, "", $devs)
    If $devs > 1 Then
    If $devs = 2 Then $dev2 = TrayCreateItem($devnamen[2]&" " & $devnamenalt[2])
    If $devs = 3 Then $dev3 = TrayCreateItem($devnamen[3]&" " & $devnamenalt[3])
    EndIf

    [/autoit][autoit][/autoit][autoit]

    TrayCreateItem("")
    $noblase = TrayCreateItem("Kein Traytip")
    TrayCreateItem("")
    $exititem = TrayCreateItem("Beenden")

    [/autoit][autoit][/autoit][autoit]

    TraySetState()
    TraySetClick(1)
    ;~ MsgBox(0, "", $devs)
    While 1
    $msg = TrayGetMsg()
    Sleep(500)
    Select
    Case $msg = $dev0
    Run(@TempDir & "\SDAD.exe" & " " & $reg[0] & " " & "communications", "", @SW_HIDE)
    Run(@TempDir & "\SDAD.exe" & " " & $reg[0] & " " & "multimedia", "", @SW_HIDE)
    If $blase = 1 Then TrayTip("Sounddevice", "" & $devnamen[0], 5, 1)
    TrayItemSetState($dev0&" "&$devnamenalt[0], $TRAY_DISABLE)
    ;~ Sleep(3000)
    Case $msg = $dev1
    Run(@TempDir & "\SDAD.exe" & " " & $reg[1] & " " & "communications", "", @SW_HIDE)
    Run(@TempDir & "\SDAD.exe" & " " & $reg[1] & " " & "multimedia", "", @SW_HIDE)
    If $blase = 1 Then TrayTip("Sounddevice", "" & $devnamen[1], 5, 1)
    TrayItemSetState($dev1&" "&$devnamenalt[1], $TRAY_DISABLE)
    ;~ Sleep(3000)
    EndSelect
    If $devs > 1 Then
    Select
    Case $msg = $dev2
    Run(@TempDir & "\SDAD.exe" & " " & $reg[2] & " " & "communications", "", @SW_HIDE)
    Run(@TempDir & "\SDAD.exe" & " " & $reg[2] & " " & "multimedia", "", @SW_HIDE)
    If $blase = 1 Then TrayTip("Sounddevice", "" & $devnamen[2], 5, 1)
    TrayItemSetState($dev2&" "&$devnamenalt[2], $TRAY_DISABLE)
    ;~ Sleep(3000)
    EndSelect
    EndIf
    If $devs > 2 Then
    Select
    Case $msg = $dev3
    Run(@TempDir & "\SDAD.exe" & " " & $reg[3] & " " & "communications", "", @SW_HIDE)
    Run(@TempDir & "\SDAD.exe" & " " & $reg[3] & " " & "multimedia", "", @SW_HIDE)
    If $blase = 1 Then TrayTip("Sounddevice", "" & $devnamen[3], 5, 1)
    TrayItemSetState($dev3&" "&$devnamenalt[3], $TRAY_DISABLE)
    ;~ Sleep(3000)
    EndSelect
    EndIf
    Select
    Case $msg = $noblase
    If $blase = 1 Then
    $blase = 0
    Else
    $blase = 1
    TrayTip("", "Traytips werden wieder angezeigt", 5, 1)
    EndIf
    Case $msg = $exititem
    ExitLoop
    EndSelect
    WEnd

    [/autoit][autoit][/autoit][autoit][/autoit]

    I spent 10 minutes reviewing code and thinking "What kind of drugs is this guy on?" before realizing it was something I wrote.