Author Topic: WASAPI device icons  (Read 827 times)

3delite

  • Posts: 925
WASAPI device icons
« on: 12 Jan '17 - 07:34 »
Hi!

Is there a way to get the WASAPI audio device icons?



The following code seems working when querying 'PKEY_Device_FriendlyName', returns the same string as BASS gives, but 'PKEY_AudioEndpointLogo_IconPath' always returns nil:

Code: [Select]
function TFormMain.GetWASAPIIcon(DeviceID: String): String;
var
    MMDeviceEnumerator: IMMDeviceEnumerator;
    MMDevice: IMMDevice;
    HR: HResult;
    PropertyStore: IPropertyStore;
    pv: PROPVARIANT;
begin
    Result := '';

    if CheckWin32Version(6, 0) then begin// The Core Audio APIs were introduced in Windows Vista.

        HR := CoCreateInstance(CLSID_MMDeviceEnumerator, nil, CLSCTX_ALL,
          IMMDeviceEnumerator, MMDeviceEnumerator);
        if Failed(HR) then
          Exit;

        HR := MMDeviceEnumerator.GetDevice(PChar(DeviceID), MMDevice);
        if Failed(HR) then
          Exit;

        HR := MMDevice.OpenPropertyStore(STGM_READ, PropertyStore);
        if Failed(HR) then
          Exit;

        // Initialize container for property value.
        PropVariantInit(pv);

        HR := PropertyStore.GetValue(PKEY_AudioEndpointLogo_IconPath, pv);
        if Failed(HR) then
          Exit;

        Result := pv.pwszVal;

        PropVariantClear(pv);

    end;
end;

Any suggestions?

Thank you!

EWeiss

  • Posts: 364
Re: WASAPI device icons
« Reply #1 on: 12 Jan '17 - 15:52 »
i can only see the IconPath is called from IAudioSessionControl
will return 0 on IMMDevice

Code: [Select]
   PKEY_AudioEndpointLogo_IconPath: TPropertyKey = (
                fmtid: (D1:$f1ab780d; D2:$2010; D3: $4ed3;
                D4: ($a3, $a6, $8b, $87, $f0, $f0, $c4, $76));
                pid: 1);

Code: [Select]
    PropVariantInit(AudioEndpointLogo);
    HR := propertyStore.GetValue(PKEY_AudioEndpointLogo_IconPath, AudioEndpointLogo);
    if HR <> S_OK then
      raise Exception.Create('Unable to retrieve IconPath !');

    if AudioEndpointLogo.vt = VT_LPWSTR  then
    begin
      LogoPath := @LogoPathBuf[0];
{$IFDEF UNICODE}
      StrCopy(LogoPath, AudioEndpointLogo.pwszVal);
{$ELSE}
      StrCopyW(LogoPath, AudioEndpointLogo.pwszVal, 127);
{$ENDIF}
      Result.LogoPath := LogoPath;
    end;

greets

3delite

  • Posts: 925
Re: WASAPI device icons
« Reply #2 on: 12 Jan '17 - 20:15 »
Tried to query with IAudioSessionControl but I still get empty string always.

If you managed to get the icon path, please share your code! It would be helpful.

Code: [Select]
function TFormMain.GetWASAPIIcon(DeviceID: String): String;
var
    MMDeviceEnumerator: IMMDeviceEnumerator;
    MMDevice: IMMDevice;
    HR: HResult;
    PropertyStore: IPropertyStore;
    pv: PROPVARIANT;
    AudioSessionControl: IAudioSessionControl;
    MMDeviceCollection: IMMDeviceCollection;
    DeviceCount: Cardinal;
    IDStr: PChar;
    i: Integer;
    AudioSessionManager: IAudioSessionManager;
    IconPath: PChar;
begin
    Result := '';

    if CheckWin32Version(6, 0) then begin// The Core Audio APIs were introduced in Windows Vista.

        HR := CoCreateInstance(CLSID_MMDeviceEnumerator, nil, CLSCTX_ALL, IMMDeviceEnumerator, MMDeviceEnumerator);
        if Failed(HR) then
          Exit;

        HR := MMDeviceEnumerator.EnumAudioEndpoints(eAll, DEVICE_STATEMASK_ALL, MMDeviceCollection);
        if Failed(HR) then
          Exit;

       MMDeviceCollection.GetCount(DeviceCount);

       for i := 0 to DeviceCount - 1 do begin

            MMDeviceCollection.Item(i, MMDevice);

            MMDevice.GetId(IDStr);

            if String(IDStr) = DeviceID then begin

                MMDevice.Activate(IID_IAudioSessionManager, CLSCTX_ALL, nil, AudioSessionManager);

                AudioSessionManager.GetAudioSessionControl(@IID_IAudioSessionControl, 0, AudioSessionControl);

                AudioSessionControl.GetIconPath(IconPath);

                Result := IconPath;

                Break;

            end;

       end;

    end;
end;

Thanks!

EWeiss

  • Posts: 364
Re: WASAPI device icons
« Reply #3 on: 13 Jan '17 - 10:08 »
i think you can not get the Icon Path if your use a 32Bit application.
do not forgot the Dialog for Sound under W7 64Bit come from a  64 Bit DLL (i think)
test it with a 64Bit Application.
i hope it work then.

greets

everson.clei

  • Posts: 22
Re: WASAPI device icons
« Reply #4 on: 13 Jan '17 - 11:22 »
Hello,

3delite, try to download the example of this link (http://www.delphipraxis.net/183977-wasapi-loopback-audio-capturing.html ) where it has a class (MMDevApi.pas) and there are the methods:

  IAudioSessionControl = interface(IUnknown)
  ['{F4B1A599-7266-4319-A8CA-E70ACB11E8CD}']
   function GetIconPath(out pRetVal: LPWSTR): HResult; stdcall; // pRetVal must be freed by CoTaskMemFree
   function SetIconPath(Value: LPCWSTR; EventContext: pGuid): HResult; stdcall;

I have not tested the codes, but maybe these methods should help you recover the icons!   

greetings

3delite

  • Posts: 925
Re: WASAPI device icons
« Reply #5 on: 13 Jan '17 - 14:12 »
Tested both functions built to Win64, still both just return an empty string always.

Tried the unit from the link, no change. Although I was using MfPack, seems to be more complete.

It would be cool if a variable 'IconPath: PWideChar' would be added to BASS_WASAPI_DEVICEINFO structure. It would be useful if it is possible at all to get the icon path somehow. :-\

Thanks for helping so far!

EWeiss

  • Posts: 364
Re: WASAPI device icons
« Reply #6 on: 20 May '18 - 16:50 »
i have create a System mixer..
my Trouble which i have is IAudioSessionEvents and OnSessionDisconnected
if you has any idea why the Event is never fired?

vorher.. Image
that is visible before call any AudioApplication

nachher.. Image
is visible after start my Virtual Piano.. from OTTB.

greets

3delite

  • Posts: 925
Re: WASAPI device icons
« Reply #7 on: 21 May '18 - 21:41 »
Not using these interfaces myself, what BASS presents is enough for me so far. I only needed the icons... Sorry!

Maybe someone has more info.

EWeiss

  • Posts: 364
Re: WASAPI device icons
« Reply #8 on: 28 May '18 - 18:01 »
Not using these interfaces myself, what BASS presents is enough for me so far. I only needed the icons... Sorry!

Maybe someone has more info.

i have Change it..

greets
« Last Edit: 29 May '18 - 06:50 by EWeiss »

EWeiss

  • Posts: 364
Re: WASAPI device icons
« Reply #9 on: 29 May '18 - 05:22 »
Ok i have found the solution..

And it works fine.
I can also show all the icons that the user changed in the Sound Dialog.
No matter which device

but NOT with Bass.

i do it self..

greets

« Last Edit: 5 Jun '18 - 16:53 by EWeiss »