[wdmaudiodev] Re: Dynamic format negotiation on Windows 7

  • From: "Cheng-mean Liu (SOCCER)" <soccerl@xxxxxxxxxxxxx>
  • To: "wdmaudiodev@xxxxxxxxxxxxx" <wdmaudiodev@xxxxxxxxxxxxx>
  • Date: Wed, 10 Feb 2010 18:32:12 +0000

Hi Kishore:

 This is a whitepaper on " Windows 7 Changes Related to Audio Drivers", it has 
a section called "Dynamic Format Change Support", that has instructions on how 
to do it.
This whitepaper is in the final stage of getting published to WHDC site.

Here is the information I cut from the current state of this paper. Let me know 
if you have any question in implementing this feature.


Dynamic Format Change is a new feature in Windows 7. This feature allows the 
format used to stream audio data between an audio application and an audio 
adapter to be changed dynamically. Before Windows 7, once an audio driver was 
loaded there was no way for drivers to notify the audio stack that its format 
capabilities had changed and needed to be reparsed without unloading and 
reloading the driver.
The following are some scenarios in which dynamic format change is used:

.       Some audio devices have hardware buttons or switches that a user can 
control to dynamically change the audio data format.  Users needed to unload 
and reload the driver to get the new capabilities before Windows 7.

.       The supported formats available to an HDMI audio endpoint are related 
to the active display mode.  When switching display modes before Windows 7, 
HDMI endpoints ended up with an incorrect list of supported formats if the 
driver was not unloaded and reloaded.
System effects (SysFX) audio processing objects (APOs) that come with third 
party driver packages might add new device formats such as AC3 in an encoding 
APO.  When this APO was disabled before Windows 7 (most likely from the user 
interface), the lack of supported format change notification caused the wrong 
supported format list to be exposed. There are two methods for triggering the 
audio stack to re-evaluate a device's format capabilities in Windows 7:

.       One method is for the audio driver to initiate a kernel streaming event 
(KSEVENT) to notify the audio stack of a device format capability change.  To 
do so, use the KSEVENTSETID_PinCapsChange event set and its 
KSEVENT_PINCAPS_FORMATCHANGE event  that were added to Windows 7. See 
KSEVENT_PINCAPS_FORMATCHANGE in MSDN for details.
.       The other method is through the IAudioEndpointFormatControl  interface 
on the endpoint for multimedia device API (MMDevApi) applications. An MMDevApi 
client, such as an IHV's APO,  can call IAudioEndpointFormatControl:: 
ResetToDefault on an endpoint to request the audio stack to re-evaluate an 
endpoint's device format capabilities.  For more details, see 
IAudioEndpointFormatControl Interface at MSDN. 

The following is sample code for a portcls-based miniport driver that uses 
KSEVENT_PINCAPS_FORMATCHANGE event. Similar to the way volume events are 
defined and used for topology filters, format change events are defined and 
used on wave filters. 
//Declare an event item for format change

static PCEVENT_ITEM PinFormatChangeEventTable[] =
{
  {
    &KSEVENTSETID_PinCapsChange,   // Something on the pin changed!
    KSEVENT_PINCAPS_FORMATCHANGE,  // Format changes
    KSEVENT_TYPE_ENABLE | KSEVENT_TYPE_BASICSUPPORT,
    WaveEventHandlerRT
  }
};

// Create a automation table

DEFINE_PCAUTOMATION_TABLE_PROP_EVENT(WaveFilterAutomationTable, 
YourPropertiesWaveFilter, PinFormatChangeEventTable);

// Use this automation table in the wave filter 

static PCFILTER_DESCRIPTOR MiniportFilterDescriptor =
{
    0,                               // Version
    &WaveFilterAutomationTable,      // AutomationTable
    sizeof(PCPIN_DESCRIPTOR),        // PinSize
    SIZEOF_ARRAY(MiniportPins),      // PinCount
    MiniportPins,                    // Pins
    sizeof(PCNODE_DESCRIPTOR),       // NodeSize
    SIZEOF_ARRAY(MiniportNodes),     // NodeCount
    MiniportNodes,                   // Nodes
    SIZEOF_ARRAY(MiniportConnections),  // ConnectionCount
    MiniportConnections,             // Connections
    0,                               // CategoryCount
    NULL                             // Categories  - use defaults (audio, 
render, capture)
}; 

WaveEventHandlerRT(__in PPCEVENT_REQUEST _pEventRequest)
{
      . 
      switch (_pEventRequest->EventItem->Id)
      {
           case KSEVENT_PINCAPS_FORMATCHANGE:
                    status = EventHandlerFormatChange(_pEventRequest);
                    break;
           default:
                    .
                    break;
      }
      ..
}

// This routine handles the event ADD and REMOVE
NTSTATUS EventHandlerFormatChange(__in PPCEVENT_REQUEST _pEventRequest)
{
.
      switch (_pEventRequest->Verb)
      {
               case PCEVENT_VERB_SUPPORT:
                       //  BasicSupport Query for Event
                       //
                       break;
               case PCEVENT_VERB_ADD:
                       //  Adding Event
                       // If we have the interface and EventEntry is defined ...
                       if ((_pEventRequest->EventEntry) && m_pPortEvents)
                       {
                                 
m_pPortEvents->AddEventToEventList(_pEventRequest->EventEntry);
                       }
                       else
                       {
                                SET_STATUS_AND_JUMP(STATUS_UNSUCCESSFUL, exit);
                       }
                       break;
               case PCEVENT_VERB_REMOVE:
                      // We cannot remove the event but we can stop generating 
the
                      // events. However, it also doesn't hurt to always 
generate them ...
                      //  Removing Event
                      .
                     break;
              default:
                    SET_STATUS_AND_JUMP(STATUS_INVALID_PARAMETER, exit);
                   break;
          }
          status = STATUS_SUCCESS;
exit:
.
  return status;
}

// Driver calls GenerateEventList to notify audio stack that supported formats 
have been changed,
// which will cause format capability queries from audio stack.

NTSTATUS CMiniportHelper::GenerateFormatChangeEvent()
{
  NTSTATUS  ntStatus = STATUS_INVALID_DEVICE_REQUEST;

      if (m_pPortEvents != NULL)
      {
             GUID gEventSet = KSEVENTSETID_PinCapsChange;
              m_pPortEvents->GenerateEventList(&gEventSet,                    
// event set
                                              KSEVENT_PINCAPS_FORMATCHANGE,   
// event id
                                              TRUE,                           
// this is a pin event
                                              PIN_NUMBER_ZERO,                
// pin id for the wave data pin                                                 
                
                                              FALSE,                          
// not a node event
                                              ULONG(-1));                     
// an invalid node id
              ntStatus = STATUS_SUCCESS;
       }
       return ntStatus;
}
The following example shows how an MMDevApi client can call 
IAudioEndpointFormatControl:: ResetToDefault on an endpoint.  

     CComPtr<IAudioEndpointFormatControl> spEndpointFormat;

            hr = m_spEndpoint->Activate(__uuidof(IAudioEndpointFormatControl), 
                                                                 CLSCTX_ALL, 
NULL,
                                                                 (void 
**)&spEndpointFormat);
            ..
            hr = spEndpointFormat->ResetToDefault(0);
            .

Thanks

Cheng-mean 

-----Original Message-----
From: wdmaudiodev-bounce@xxxxxxxxxxxxx 
[mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx] On Behalf Of K93157
Sent: Wednesday, February 10, 2010 10:11 AM
To: wdmaudiodev@xxxxxxxxxxxxx
Subject: [wdmaudiodev] Dynamic format negotiation on Windows 7

Hi,

I am a trying to get our audio driver to work on windows 7. The audio driver is 
a WavePCI Miniport driver. Out audio device wants to provide different sample 
rates, bits per sample depending on the configuration that changes dymanically.

This was not a problem in XP as it renegotiates for every new stream. However 
in case of Windows 7, Windows is chosing one sample rate or bits per sample at 
the install time and using it every time. 

I read through various related posts on this list and followed the suggestions 
given

1) I added an Automation Table with event to a Node ( Waveout Volume Node) 
2) I am providing the above automation table in GetDescription correctly
3) I am calling GenerateEventList on port driver when internal config of our 
device changes. 
4) The generateEventList call seems successful, but Windows (port Driver) is 
NOT renegotiating format.
 
I don't have any clue on what is going on. Am I missing anything?
 
I appreicate any help 
 
Thanks
Kishore


      

******************

WDMAUDIODEV addresses:
Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx
Subscribe:    mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe
Unsubscribe:  mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe
Moderator:    mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx

URL to WDMAUDIODEV page:
http://www.wdmaudiodev.com/


******************

WDMAUDIODEV addresses:
Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx
Subscribe:    mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe
Unsubscribe:  mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe
Moderator:    mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx

URL to WDMAUDIODEV page:
http://www.wdmaudiodev.com/

Other related posts: