• raziel024

    With pure lua I don't think so, personally I made an Autohotkey companion app to control all relative to sound (without keyboard, so is more eficiently). But some apps like nircmd could do the work also.

    posted in Volume read more
  • raziel024

    This community really sucks, 4 days and no replies? I'm out of here

    posted in Q&A read more
  • raziel024

    I want to be able to modify the value of some variables of my custom remote. Since right now, for the limitations of Unified Server, I have to use a companion app to my remote, but there's no way I know to write the "info" catched by the companion app. If only I can modify variables...

    posted in Q&A read more
  • raziel024

    Could you add checkboxes in list items, so they can be selected/deselected, and multiple selections can be allowed? RIght now the lists are basically arcaic.

    posted in Media read more
  • raziel024

    Is something related with device battery or what? For me, I want to skip chapters autmatically from the series I watch using my custom remote for MPC, and the obvius thing is create an alarm that runs no matter if the remote in the app is on front or not, but what are the downsides? Aclaration is required, please

    posted in Q&A read more
  • raziel024

    I already did obviously is the way to approach, but there's no example about this kind of stuff, as my question says, so...

    posted in Q&A read more
  • raziel024

    Seems like things going extremely slowly here, bah!

    posted in Q&A read more
  • raziel024

    Hi, I'm currently developed a custom remote for advanced use of Media Player Classic, which can retrieve thinks like playlist, audio and subtitles list and more stuff, the problem is that, for achieving this kind of thing, it needs to send and receive WM_COPYDATA messages, and since I don't know how to this with pure Lua I have to use a companion app written in autohotkey, and recurre to temp files. Is there's somebody who can give me an example to use this type of messages directly in lua?
    For anyone, this is the ahk code:

    #SingleInstance force
    SetKeyDelay, -1
    OnMessage(0x4a, "On_WM_COPYDATA")
    OnMessage(0x1513, "On_URCall")
    menu, tray, add, Vars
    SetWorkingDir, %A_ScriptDir%
    file := A_ScriptDir . "\file.prop"
    FileEncoding, UTF-8
    Gui +LastFound
    hWnd := WinExist()
    DetectHiddenWindows On
    ;    // :=:=:=:= Commands from MPC-HC to host
    
    ;    // Send after connection
    ;    // Parameter 1: MPC-HC window handle (command should be sent to this HWnd)
        global CMD_CONNECT             := 0x50000000 
    
    ;    // Send when opening or closing file
    ;    // Parameter 1: current state (see MPC_LOADSTATE enum)
        global CMD_STATE               := 0x50000001 
    
    ;    // Send when playing  pausing or closing file
    ;    // Parameter 1: current play mode (see MPC_PLAYSTATE enum)
        global CMD_PLAYMODE            := 0x50000002 
    
    ;    // Send after opening a new file
    ;    // Parameter 1: title
    ;    // Parameter 2: author
    ;    // Parameter 3: description
    ;    // Parameter 4: complete filename (path included)
    ;    // Parameter 5: duration in seconds
        global CMD_NOWPLAYING          := 0x50000003 
    
    ;    // List of subtitle tracks
    ;    // Parameter 1: Subtitle track name 0
    ;    // Parameter 2: Subtitle track name 1
    ;    // ...
    ;    // Parameter n: Active subtitle track  -1 if subtitles are disabled
    ;    //
    ;    // if no subtitle track present  returns -1
    ;    // if no file loaded  returns -2
        global CMD_LISTSUBTITLETRACKS  := 0x50000004 
    
    ;    // List of audio tracks
    ;    // Parameter 1: Audio track name 0
    ;    // Parameter 2: Audio track name 1
    ;    // ...
    ;    // Parameter n: Active audio track
    ;    //
    ;    // if no audio track is present  returns -1
    ;    // if no file is loaded  returns -2
        global CMD_LISTAUDIOTRACKS     := 0x50000005 
    
    ;    // Send current playback position in response
    ;    // of global CMD_GETCURRENTPOSITION.
    ;    // Parameter 1: current position in seconds
        global CMD_CURRENTPOSITION     := 0x50000007 
    
    ;    // Send the current playback position after a jump.
    ;    // (Automatically sent after a seek event).
    ;    // Parameter 1: new playback position (in seconds).
        global CMD_NOTIFYSEEK          := 0x50000008 
    
    ;    // Notify the end of current playback
    ;    // (Automatically sent).
    ;    // Parameter 1: none.
        global CMD_NOTIFYENDOFSTREAM   := 0x50000009 
    
    ;    // Send version str
    ;    // Parameter 1: MPC-HC's version
        global CMD_VERSION             := 0x5000000A 
    
    ;    // List of files in the playlist
    ;    // Parameter 1: file path 0
    ;    // Parameter 2: file path 1
    ;    // ...
    ;    // Parameter n: active file  -1 if no active file
        global CMD_PLAYLIST            := 0x50000006 
    
    ;    // Send information about MPC-HC closing
        global CMD_DISCONNECT          := 0x5000000B 
    
    ;    // :=:=:=:= Commands from host to MPC-HC
    
    ;    // Open new file
    ;    // Parameter 1: file path
        global CMD_OPENFILE            := 0xA0000000 
    
    ;    // Stop playback  but keep file / playlist
        global CMD_STOP                := 0xA0000001 
    
    ;    // Stop playback and close file / playlist
        global CMD_CLOSEFILE           := 0xA0000002 
    
    ;    // Pause or restart playback
        global CMD_PLAYPAUSE           := 0xA0000003 
    
    ;    // Unpause playback
        global CMD_PLAY                := 0xA0000004 
    
    ;    // Pause playback
        global CMD_PAUSE               := 0xA0000005 
    
    ;    // Add a new file to playlist (did not start playing)
    ;    // Parameter 1: file path
        global CMD_ADDTOPLAYLIST       := 0xA0001000 
    
    ;    // Remove all files from playlist
        global CMD_CLEARPLAYLIST       := 0xA0001001 
    
    ;    // Start playing playlist
        global CMD_STARTPLAYLIST       := 0xA0001002 
    
        global CMD_REMOVEFROMPLAYLIST  := 0xA0001003   
    
    ;    // Cue current file to specific position
    ;    // Parameter 1: new position in seconds
        global CMD_SETPOSITION         := 0xA0002000 
    
    ;    // Set the audio delay
    ;    // Parameter 1: new audio delay in ms
        global CMD_SETAUDIODELAY       := 0xA0002001 
    
    ;    // Set the subtitle delay
    ;    // Parameter 1: new subtitle delay in ms
        global CMD_SETSUBTITLEDELAY    := 0xA0002002 
    
    ;    // Set the active file in the playlist
    ;    // Parameter 1: index of the active file  -1 for no file selected
    ;    // DOESN'T WORK
        global CMD_SETINDEXPLAYLIST    := 0xA0002003 
    
    ;    // Set the audio track
    ;    // Parameter 1: index of the audio track
        global CMD_SETAUDIOTRACK       := 0xA0002004 
    
    ;    // Set the subtitle track
    ;    // Parameter 1: index of the subtitle track  -1 for disabling subtitles
        global CMD_SETSUBTITLETRACK    := 0xA0002005 
    
    ;    // Ask for a list of the subtitles tracks of the file
    ;    // return a global CMD_LISTSUBTITLETRACKS
        global CMD_GETSUBTITLETRACKS   := 0xA0003000 
    
    ;    // Ask for the current playback position 
    ;    // see global CMD_CURRENTPOSITION.
    ;    // Parameter 1: current position in seconds
        global CMD_GETCURRENTPOSITION  := 0xA0003004 
    
    ;    // Jump forward/backward of N seconds 
    ;    // Parameter 1: seconds (negative values for backward)
        global CMD_JUMPOFNSECONDS      := 0xA0003005 
    
    ;    // Ask slave for version
        global CMD_GETVERSION          := 0xA0003006 
    
    ;    // Ask for a list of the audio tracks of the file
    ;    // return a global CMD_LISTAUDIOTRACKS
        global CMD_GETAUDIOTRACKS      := 0xA0003001 
    
    ;    // Ask for the properties of the current loaded file
    ;    // return a global CMD_NOWPLAYING
        global CMD_GETNOWPLAYING       := 0xA0003002 
    
    ;    // Ask for the current playlist
    ;    // return a global CMD_PLAYLIST
        global CMD_GETPLAYLIST         := 0xA0003003 
    
    ;    // Toggle FullScreen
        global CMD_TOGGLEFULLSCREEN    := 0xA0004000 
    
    ;    // Jump forward(medium)
        global CMD_JUMPFORWARDMED      := 0xA0004001 
    
    ;    // Jump backward(medium)
        global CMD_JUMPBACKWARDMED     := 0xA0004002 
    
    ;    // Increase Volume
        global CMD_INCREASEVOLUME      := 0xA0004003 
    
    ;    // Decrease volume
        global CMD_DECREASEVOLUME      := 0xA0004004 
    
    ;    // Toggle shader
    ;    //global CMD_SHADER_TOGGLE       := 0xA0004005 
    
    ;    // Close App
        global CMD_CLOSEAPP            := 0xA0004006 
    
    ;    // Set playing rate
        global CMD_SETSPEED            := 0xA0004008 
    
    ;    // Show host defined OSD message string
        global CMD_OSDSHOWMESSAGE      := 0xA0005000
    
    global mpcHWND
    global required := 0
    ;FileDelete, test.txt
    SetFormat Integer, D
    hwnd := A_ScriptHwnd + 0
    ;WinGetClass, class, ahk_id %A_ScriptHwnd%
    ;WinGetTitle, title, ahk_id %A_ScriptHwnd%
    ;MsgBox, 0, Title, class:%class%`ntitle:%title%
    
    mpcPID := -1
    Gosub, Check        
    return
    
    Check:
    WinGet, mpcPID2, PID, ahk_class MediaPlayerClassicW
    if (mpcPID <> mpcPID2)
    {
        Process, Close, %mpcPID2%
        Run, "%1%" /slave %hwnd%,, UseErrorLevel, mpcPID
        WinWait, ahk_pid %mpcPID%,,10
        While, not mpcHWND
            Sleep, 1000
    }
    return
    
    Send(Hwnd, dwData, lpData) {
        static WM_COPYDATA := 0x4a
        VarSetCapacity(COPYDATASTRUCT, 3*A_PtrSize, 0)
        cbData := (StrLen(lpData) + 1) * (A_IsUnicode ? 2 : 1)
        NumPut(dwData, COPYDATASTRUCT, 0)
        NumPut(cbData, COPYDATASTRUCT, A_PtrSize)
        NumPut(&lpData, COPYDATASTRUCT, 2*A_PtrSize)
        ;SendMessage, % WM_COPYDATA, % Hwnd ,, &COPYDATASTRUCT
        SendMessage, % WM_COPYDATA, % A_ScriptHwnd , &COPYDATASTRUCT,, % "ahk_id " Hwnd
        return ErrorLevel == "FAIL" ? false : true
    }
    
    On_WM_COPYDATA(wParam, lParam, msg, hwnd) {
        dwData := NumGet(lParam+0, 0)
        cbData := NumGet(lParam+A_PtrSize)
        lpData := NumGet(lParam + 2*A_PtrSize)
        lpData := StrGet(lpData)
        ;FileAppend, %A_Hour%:%A_Min%:%A_Sec%:Received %lpData%`n, debug.txt
        ;si es CMD_CONNECT
        if (dwData = 1342177280)
        {
            mpcHWND := lpData
        }
        ;si es requerido
        else if required
        {
            ;ToolTip, % dwData
            ;si es CMD_PLAYLIST
            if (dwData = 1342177286)
            {
                StringReplace, lpData, lpData, \, \\, All
                WriteToSettings("playlist", lpData)
            }
            ;si es CMD_LISTSUBTITLETRACKS
            else if (dwData = 1342177284)
            {
                 WriteToSettings("subs", lpData)
            }
            ;si es CMD_LISTAUDIOTRACKS
            else if (dwData = 1342177285)
            {
                WriteToSettings("audio", lpData)
            }
            required := 0
        }
        return true
    }
    
    
    On_URCall(wParam, lParam, msg, hwnd) {
        ;FileAppend, %A_Hour%:%A_Min%:%A_Sec%:Received %wParam%`,%lParam%`n, debug.txt
        if wParam between 1 and 3
            required := 1
        static GET_PLAYLIST := 1
        static GET_AUDIO := 2
        static GET_SUBS := 3   
        static EMPTY_PLAYLIST := 4   
        static SET_SUB := 5   
        static SET_AUDIO := 6  
        static SET_PLAYLIST_INDEX := 7  
        static GET_INFO := 8
        static GET_VOL := 9
        static SET_VOL := 10
        static GET_CHAPTERS := 11
        static SET_SUBTITLE_DELAY := 12
        ;Debug("wParam:" wParam ", lParam:" lParam)
        Gosub, Check
        if (wParam = GET_PLAYLIST)
            Send(mpcHWND, CMD_GETPLAYLIST, "")
        else if (wParam = 101)
            GETSYSTEMPOWERSTATUS()
        else if (wParam = GET_AUDIO)
            Send(mpcHWND, CMD_GETAUDIOTRACKS, "")
        else if (wParam = GET_SUBS)
            Send(mpcHWND, CMD_GETSUBTITLETRACKS, "")
        else if (wParam = EMPTY_PLAYLIST)
            Send(mpcHWND, CMD_CLEARPLAYLIST, "")
        else if (wParam = SET_SUB)
        {
            if (lParam = 99)
                lParam := -1
            Send(mpcHWND, CMD_SETSUBTITLETRACK, lParam)
        }
        else if (wParam = SET_AUDIO)
            Send(mpcHWND, CMD_SETAUDIOTRACK, lParam)
        else if (wParam = SET_PLAYLIST_INDEX)
        {
            ListView_SelectnPlay(lParam)
        }
        else if (wParam = GET_INFO)
        {
            ;ToolTip, A mover el esqueleto
            GetInfo()
        }
        else if (wParam = GET_VOL)
        {
            ;ToolTip, A mover el esqueleto
            WriteToSettings("vol", VA_GetMasterVolume())
        }
        else if (wParam = SET_VOL)
        {
            ;ToolTip, A mover el esqueleto
            VA_SetMasterVolume(lParam)
        }
        else if (wParam = GET_CHAPTERS)
        {
            ;ToolTip, A mover el esqueleto
            GetChapters()
        }
           else if (wParam = SET_SUBTITLE_DELAY)
        {
            ;ToolTip, A mover el esqueleto
            Send(mpcHWND, CMD_SETSUBTITLEDELAY, lParam)
            Debug("delay:" . lParam)
        }
        return true
    }
    
    WriteToSettings(setting, value) {
        Critical
        ;exist := 0
        ;;ToolTip, Writing %setting% to settings.prop
        ;file := FileOpen("C:\ProgramData\Unified Remote\Remotes\Custom\MPC\settings2.prop", "r", "UTF-8")
        ;if !IsObject(file)
        ;    ;ToolTip, Can't open file
        ;    return false
        ;ResultString := ""  ; When writing a file this way, use `r`n rather than `n to start a new line.
        ;While not file.AtEOF
        ;{
        ;    line := file.ReadLine()      
        ;    if (!exist) && (RegExMatch(line, "i)^" . setting . ":"))
        ;    {
        ;        Debug("line:" . line)
        ;        exist := 1
        ;        line := setting . ": " . value  . "`r`n"
        ;                    Debug("Ya existe " . setting . ". Reemplazando por:" . line)
    
        ;    }
        ;    ResultString .= line
        ;}
        ;    file.Close()
        ;if not exist 
        ;{
        ;    Debug("Añadiendo " . setting . ": " . value)
        ;    ResultString .= setting . ": " . value  . "`r`n"
        ;}
        Progress, a b H10 W10,,,Helper
        file := FileOpen("C:\ProgramData\Unified Remote\Remotes\Custom\MPC\" . setting . ".prop", "w", "UTF-8")
        ;Debug("Result:" . ResultString)
        file.Write(value  . "`r`n")
        file.Close()
        Progress, Off
    }
    
    
    Debug(out) {
    FileAppend, %A_DD%/%A_MM%/%A_Year% %A_Hour%:%A_Min%:%A_Sec%:: %out% `r`n, C:\ProgramData\Unified Remote\Remotes\Custom\MPC\debug.txt
    }
    ; ----------------------------------------------------------------------------------------------------------------------
    ; Function .....: ExtListView_ToggleSelection
    ; Description ..: Select/deselect items in the target ListView.
    ; Parameters ...: objLV   - External ListView initializated object.
    ; ..............: bSelect - 1 for selection, 0 for deselection.
    ; ..............: nItem   - -1 for all items or "n" (0-based) for a specific ListView item.
    ; ----------------------------------------------------------------------------------------------------------------------
    ListView_SelectnPlay(pos) {
       ;ToolTip, pos:%pos%
       fullscreen := 0
       ;Si la ventana esta en fullscreen
        WinGet, Style, Style, ahk_class MediaPlayerClassicW
        if !(Style & 0x40000)
        {
            ;ToolTip, fullscreen!
            fullscreen := 1
            Send(mpcHWND, CMD_TOGGLEFULLSCREEN, "")
            Sleep, 100
        }
        ControlGet, list_hwnd, Hwnd,, SysListView322, ahk_class MediaPlayerClassicW
        ControlSend, , ^{Home}, ahk_id %list_hwnd%
        Loop, % pos
            ControlSend, , {Down}, ahk_id %list_hwnd%
        ControlSend, , {Space}, ahk_id %list_hwnd%
        if fullscreen
        {
            Sleep, 500
            Send(mpcHWND, CMD_TOGGLEFULLSCREEN, "")
        }
    }
    
    
    
    
    
    GETSYSTEMPOWERSTATUS() {
        VarSetCapacity(powerStatus, 1+1+1+1+4+4)  ;Size of SYSTEM_POWER_STATUS Structure 
        success:=DllCall("GetSystemPowerStatus", "UInt", &powerStatus)
        If (ErrorLevel != 0 Or success = 0)
            return
        acLineStatus := NumGet(powerStatus, 0, "Char")
        BatteryLifePercent := NumGet(powerStatus, 2, "Char")
    
            If acLineStatus = 1
                acLineStatus := "Charging"
            Else
                acLineStatus := "Discharging"
        WriteToSettings("bat", "BATTERY INFO`nLevel   : " . BatteryLifePercent . "%`nStatus  : " . acLineStatus)
        powerStatus := ""
    }
    
    VA_GetMasterVolume(channel="", device_desc="playback")
    {
        if ! aev := VA_GetAudioEndpointVolume(device_desc)
            return
        if channel =
            VA_IAudioEndpointVolume_GetMasterVolumeLevelScalar(aev, vol)
        else
            VA_IAudioEndpointVolume_GetChannelVolumeLevelScalar(aev, channel-1, vol)
        ObjRelease(aev)
        return Round(vol*100,0)
    }
    
    VA_SetMasterVolume(vol, channel="", device_desc="playback")
    {
        vol := vol>100 ? 100 : vol<0 ? 0 : vol
        if ! aev := VA_GetAudioEndpointVolume(device_desc)
            return
        if channel =
            VA_IAudioEndpointVolume_SetMasterVolumeLevelScalar(aev, vol/100)
        else
            VA_IAudioEndpointVolume_SetChannelVolumeLevelScalar(aev, channel-1, vol/100)
        ObjRelease(aev)
    }
    
    VA_IAudioEndpointVolume_SetMasterVolumeLevel(this, LevelDB, GuidEventContext="") {
        return DllCall(NumGet(NumGet(this+0)+6*A_PtrSize), "ptr", this, "float", LevelDB, "ptr", VA_GUID(GuidEventContext))
    }
    VA_IAudioEndpointVolume_SetChannelVolumeLevelScalar(this, Channel, Level, GuidEventContext="") {
        return DllCall(NumGet(NumGet(this+0)+11*A_PtrSize), "ptr", this, "uint", Channel, "float", Level, "ptr", VA_GUID(GuidEventContext))
    }
    VA_IAudioEndpointVolume_GetMasterVolumeLevel(this, ByRef LevelDB) {
        return DllCall(NumGet(NumGet(this+0)+8*A_PtrSize), "ptr", this, "float*", LevelDB)
    }
    VA_IAudioEndpointVolume_GetMasterVolumeLevelScalar(this, ByRef Level) {
        return DllCall(NumGet(NumGet(this+0)+9*A_PtrSize), "ptr", this, "float*", Level)
    }
    VA_IAudioEndpointVolume_SetMasterVolumeLevelScalar(this, Level, GuidEventContext="") {
        return DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "float", Level, "ptr", VA_GUID(GuidEventContext))
    }
    VA_IAudioEndpointVolume_GetChannelVolumeLevelScalar(this, Channel, ByRef Level) {
        return DllCall(NumGet(NumGet(this+0)+13*A_PtrSize), "ptr", this, "uint", Channel, "float*", Level)
    }
    VA_IMMDeviceEnumerator_GetDevice(this, id, ByRef Device) {
        return DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), "ptr", this, "wstr", id, "ptr*", Device)
    }
    VA_IMMDeviceEnumerator_GetDefaultAudioEndpoint(this, DataFlow, Role, ByRef Endpoint) {
        return DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this, "int", DataFlow, "int", Role, "ptr*", Endpoint)
    }
    VA_IMMDeviceEnumerator_EnumAudioEndpoints(this, DataFlow, StateMask, ByRef Devices) {
        return DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "int", DataFlow, "uint", StateMask, "ptr*", Devices)
    }
    VA_IMMDeviceCollection_Item(this, Index, ByRef Device) {
        return DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this, "uint", Index, "ptr*", Device)
    }
    VA_IMMDeviceCollection_GetCount(this, ByRef Count) {
        return DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "uint*", Count)
    }
    VA_IMMDevice_OpenPropertyStore(this, Access, ByRef Properties) {
        return DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this, "uint", Access, "ptr*", Properties)
    }
    VA_WStrOut(ByRef str) {
        str := StrGet(ptr := str, "UTF-16")
        DllCall("ole32\CoTaskMemFree", "ptr", ptr)  ; FREES THE STRING.
    }
    VA_IMMDevice_Activate(this, iid, ClsCtx, ActivationParams, ByRef Interface) {
        return DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "ptr", VA_GUID(iid), "uint", ClsCtx, "uint", ActivationParams, "ptr*", Interface)
    }
    VA_GUID(ByRef guid_out, guid_in="%guid_out%") {
        if (guid_in == "%guid_out%")
            guid_in :=   guid_out
        if  guid_in is integer
            return guid_in
        VarSetCapacity(guid_out, 16, 0)
        DllCall("ole32\CLSIDFromString", "wstr", guid_in, "ptr", &guid_out)
        return &guid_out
    }
    VA_GetAudioEndpointVolume(device_desc="playback")
    {
        if ! device := VA_GetDevice(device_desc)
            return 0
        VA_IMMDevice_Activate(device, "{5CDF2C82-841E-4546-9722-0CF74078229A}", 7, 0, endpointVolume)
        ObjRelease(device)
        return endpointVolume
    }
    VA_GetDevice(device_desc="playback")
    {
        static CLSID_MMDeviceEnumerator := "{BCDE0395-E52F-467C-8E3D-C4579291692E}"
            , IID_IMMDeviceEnumerator := "{A95664D2-9614-4F35-A746-DE8DB63617E6}"
        if !(deviceEnumerator := ComObjCreate(CLSID_MMDeviceEnumerator, IID_IMMDeviceEnumerator))
            return 0
        
        device := 0
        
        if VA_IMMDeviceEnumerator_GetDevice(deviceEnumerator, device_desc, device) = 0
            goto VA_GetDevice_Return
        
        if device_desc is integer
        {
            m2 := device_desc
            if m2 >= 4096 ; Probably a device pointer, passed here indirectly via VA_GetAudioMeter or such.
            {
                ObjAddRef(device := m2)
                goto VA_GetDevice_Return
            }
        }
        else
            RegExMatch(device_desc, "(.*?)\s*(?::(\d+))?$", m)
        
        if m1 in playback,p
            m1 := "", flow := 0 ; eRender
        else if m1 in capture,c
            m1 := "", flow := 1 ; eCapture
        else if (m1 . m2) = ""  ; no name or number specified
            m1 := "", flow := 0 ; eRender (default)
        else
            flow := 2 ; eAll
        
        if (m1 . m2) = ""   ; no name or number (maybe "playback" or "capture")
        {
            VA_IMMDeviceEnumerator_GetDefaultAudioEndpoint(deviceEnumerator, flow, 0, device)
            goto VA_GetDevice_Return
        }
    
        VA_IMMDeviceEnumerator_EnumAudioEndpoints(deviceEnumerator, flow, 1, devices)
        
        if m1 =
        {
            VA_IMMDeviceCollection_Item(devices, m2-1, device)
            goto VA_GetDevice_Return
        }
        
        VA_IMMDeviceCollection_GetCount(devices, count)
        index := 0
        Loop % count
            if VA_IMMDeviceCollection_Item(devices, A_Index-1, device) = 0
                if InStr(VA_GetDeviceName(device), m1) && (m2 = "" || ++index = m2)
                    goto VA_GetDevice_Return
                else
                    ObjRelease(device), device:=0
    
    VA_GetDevice_Return:
        ObjRelease(deviceEnumerator)
        if devices
            ObjRelease(devices)
        
        return device ; may be 0
    }
    
    VA_GetDeviceName(device)
    {
        static PKEY_Device_FriendlyName
        if !VarSetCapacity(PKEY_Device_FriendlyName)
            VarSetCapacity(PKEY_Device_FriendlyName, 20)
            ,VA_GUID(PKEY_Device_FriendlyName :="{A45C254E-DF1C-4EFD-8020-67D146A850E0}")
            ,NumPut(14, PKEY_Device_FriendlyName, 16)
        VarSetCapacity(prop, 16)
        VA_IMMDevice_OpenPropertyStore(device, 0, store)
        ; store->GetValue(.., [out] prop)
        DllCall(NumGet(NumGet(store+0)+5*A_PtrSize), "ptr", store, "ptr", &PKEY_Device_FriendlyName, "ptr", &prop)
        ObjRelease(store)
        VA_WStrOut(deviceName := NumGet(prop,8))
        return deviceName
    }
    
    
    

    Note: the ahk also implements some functions to retrieve the volume stuff
    Thanks.

    posted in Q&A read more

Internal error.

Oops! Looks like something went wrong!