Answered How to use CoreAudio API in Metro app

  • 13 April 2012 10:41
     
     

    I write a dll for metro app and desktop app use. The function of the DLL is to discovery Audio Device Topology. We use the WASAPI to discovery all Audio Endpoint. In desktop app the dll is function correctly. But in Metro app when we call interface IConnect member function "GetConnectedTo" it always failed. we got follow error. 

    GetLastError = 0x05

    HResult =  0x80070005

    http://msdn.microsoft.com/en-us/library/windows/desktop/dd371061(v=vs.85).aspx

    Does WASAPI is allow to called in Metro app? Does here has any sample code address how to use it in Metro app?

    Please help me!!!!!! Thanks.


Semua Balasan

  • 13 April 2012 19:40
    Moderator
     
     Jawab

    Hi Robert,

    Parts of WASAPI can be used in Metro style apps, but not all. If you look at the documentation for the various interfaces each will say which environment it applies to. The DeviceTopology interfaces in general and IConnect::GetConnectedTo in particular say "Applies to: desktop apps only" and so are cannot be successfully called from Metro style apps. Contrast this with IAudioClient which is available to Metro style apps and is marked "Applies to: desktop apps | Metro style apps"

    --Rob

  • 18 April 2012 2:07
     
     

    Many  APIs it say "Applies to: desktop apps only" but we still can be successfully called from Metro style apps.

    Example:

    The IMMDeviceEnumerator::EnumAudioEndpoints (IDeviceTopology::GetConnector )method in particular say "Applies to: desktop apps only".

    Is this wrote the wrong word on document??

    http://msdn.microsoft.com/en-us/library/windows/desktop/dd371400(v=vs.85).aspx




  • 18 April 2012 2:43
     
      Memiliki Kode

    I am confused.

    The method  IMMDevice::Activate in particular say "Applies to:desktop apps only".

    But IAudioEndpointVolume in particular say  Applies to: desktop apps | Metro style apps

    IMMDevice *pDevice=NULL; 

    hr=pDevice->Activate(__uuidof(IAudioEndpointVolume),CLSCTX_ALL,NULL,(void **)(&pVolumeAPI));  

    if IMMDevice::Activate  can not be used, how can we get IAudioEndpointVolume  interface ?




  • 19 April 2012 23:18
    Moderator
     
     Jawab

    The documentation is correct. This API should be stubbed out and should not return valid data. You shouldn't need to use IMMDevice in the WinRT environment.

    -James


    Windows Media SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/


  • 19 April 2012 23:28
    Moderator
     
     Saran Jawaban Memiliki Kode

    You can get the underlying audio endpoint but you must use the WinRT APIs to access the device.

    Platform::String^ id = Windows::Media::Devices::MediaDevice::GetDefaultAudioCaptureId(Windows::Media::Devices::AudioDeviceRole::Console );
     
    Microsoft::WRL::ComPtr<IAudioClient> pAudioClient = NULL;
     
    ActivateAudioInterface( id->Data(), __uuidof( IAudioClient ), (void**)&pAudioClient );

    I hope this helps,

    James


    Windows Media SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

  • 20 April 2012 1:36
     
      Memiliki Kode

    Thanks for your help~~

    BUT my DLL is not WinRT DLL ,and we use Win32 DLL to get IMMDevice interface. Is it possibly(use LoadPackageLibrary)?



    And if we want change to WinRT DLL did you have more sample code about Core audio use WinRT APIs ?

    Ex:

    1.IPropertyStore GetValue/SetValue for APO(custome effect).

    hr = pDevice->OpenPropertyStore(STGM_READ,&pProperties);  
    PROPVARIANT varName;  
    PropVariantInit(&varName);  
    hr = pProperties->GetValue(PKEY_APO_KEY, &varName);  

    2.if our audio device is not default could we control it?

    3.if we have 2  or more audio endpoints  could we streaming to not default default device? 



  • 23 April 2012 21:33
    Moderator
     
     

    1) You can only load your DLL from Metro if it doesn't use any APIs that are explicitly banned for use in the Metro environment. Most of the time you will need to modify your DLL so that it uses only the APIs that are allowed from the Metro environment.

    2) You can choose what audio device endpoint to instantiate at runtime. You do not have to use the default device. See the following link for more information: http://msdn.microsoft.com/en-us/library/windows/apps/hh464974.aspx

    3) I apologize but I don't understand this question. Please rephrase it and I will do what I can to answer it for you.

    I hope this helps,

    James


    Windows Media SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

  • 26 April 2012 3:14
     
     

    thanks James~

    Yes, we can use " FindAllAsync" to enumerate the audio endpoint but i got another problem.

    1.Before ActivateAudioInterface i want get a symbolic link to call CreateDeviceAccessInstance to specific our device and now i can not get enough information in DeviceInformationCollection  interface.

    2.I can not get endpoint type in DeviceInformationCollection  interface.

    example : Line in ,Mic ,Sperker, Headphone.

    Any information you can provide me would be greatly appreciated.


  • 27 April 2012 23:28
    Moderator
     
     

    Hello Robert,

    How are you checking for the endpoint type? Are you enumerating through the properties? Is this information not included?

    DeviceInformation.Properties
    http://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.enumeration.deviceinformation.properties.aspx

    -James


    Windows Media SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

  • 30 April 2012 2:35
     
     

    We had check that "DeviceInformation.Properties" is not include endpoint type.

    Enumerating through the properties as below.

    System.Devices.Icon

    System.ItemNameDisplay

    System.Devices.IsDefault

    System.Devices.DeviceInstanceID

    System.Devices.InterfaceEnable

     

  • 01 Mei 2012 22:53
    Moderator
     
     Jawab Memiliki Kode

    Hello Robert,

    Yes those are the default. If you want additional properties you need to request them.

    // Create a set of two additional properties.
        var propertiesToRetrieve = new Array();
        propertiesToRetrieve.push("System.Devices.InterfaceClassGuid");
        propertiesToRetrieve.push("System.Devices.ContainerId");
    
        Windows.Devices.Enumeration.findAllAsync(selectorString, 
                 propertiesToRetrieve).then(successCallback, errorCallback);)
    
    // Handles successful completion of the findAllAsync method.
    function successCallback(deviceInformationCollection) {
        var numDevices = deviceInformationCollection.length;
        if (numDevices) {
            for (var i = 0; i < numDevices; i++) {
                printProperties(document.getElementById("log"),
                     deviceInformationCollection[i].properties);
            }
        } 
    }
    
    // Handles an error completion of the findAllAsync method.
    function errorCallback(e) {
        document.getElementById("statusMessage").innerHTML = 
            "Failed to find devices, error: " + e.message;
    }
    
    function printProperties(log, prop) {
        log.innerHTML += "property store count is: " + prop.size;
        var pt = prop.first();
        while (pt.hasCurrent) {
            log.innerHTML += "<br />" + pt.current.key + " := " + pt.current.value;
            pt.moveNext();
        }
        log.innerHTML += "<br />";
    }
    
                                   

    Code above taken from the following page:

    http://msdn.microsoft.com/en-us/library/windows/apps/hh464997.aspx

    I hope this helps,

    James


    Windows Media SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

  • 09 Mei 2012 10:05
     
     

    Thanks~I can get endpoint type.

    I use FindAllAsync api to enumeration audio interface but it only can get enable endpoint.(Paramter:DeviceClass.AudioRender)

    But i also need to get Device (active & Unplugged & disable ).

    How can i do that??


     

  • 09 Mei 2012 21:06
    Moderator
     
     

    Hello Robert, I’m not sure that I understand what data you are looking for. If it doesn't exist when using "find all async" I'm not sure that the data exists at the metro level. However, If I understand your question correctly  using the DeviceWatcher class may give you the information you are looking for.

    DeviceWatcher class
    http://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.enumeration.devicewatcher.aspx

    I hope this helps,

    James


    Windows Media SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/