[wdmaudiodev] Re: IMiniportAudioSignalProcessing support in driver

  • From: "Jolly, David A" <david.a.jolly@xxxxxxxxx>
  • To: "wdmaudiodev@xxxxxxxxxxxxx" <wdmaudiodev@xxxxxxxxxxxxx>
  • Date: Wed, 19 Feb 2014 17:22:59 +0000

Thanks! This worked. It's a little bit confusing, because I haven't seen this 
documented anywhere online.

For anyone who's interested, I'll document what I did to get it to work.


(1)    From the sysvad example, I included that KSATTRIBUTE_LIST:

static KSATTRIBUTE PinDataRangeSignalProcessingModeAttribute =
{
    sizeof(KSATTRIBUTE),
    0,
    STATICGUIDOF(KSATTRIBUTEID_AUDIOSIGNALPROCESSING_MODE),
};

static PKSATTRIBUTE PinDataRangeAttributes[] =
{
    &PinDataRangeSignalProcessingModeAttribute,
};

static KSATTRIBUTE_LIST PinDataRangeAttributeList =
{
    ARRAYSIZE(PinDataRangeAttributes),
    PinDataRangeAttributes,
};


(2)    Next, I added the KSDATARANGE_ATTRIBUTES flag to my pin data range 
structure:

static KSDATARANGE_AUDIO PinDataRangesStream[] =
{
    {
        {
            sizeof(KSDATARANGE_AUDIO),
            KSDATARANGE_ATTRIBUTES,
            0,
            0,
            STATICGUIDOF(KSDATAFORMAT_TYPE_AUDIO),
            STATICGUIDOF(KSDATAFORMAT_SUBTYPE_PCM),
            STATICGUIDOF(KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)
        },
       MAX_CHANNELS,
        MIN_BITS_PER_SAMPLE,
        MAX_BITS_PER_SAMPLE,
        MIN_SAMPLE_RATE,
        MIN_SAMPLE_RATE
    },
};


(3)    Finally, I added an entry into my pin data range pointer array:

static PKSDATARANGE PinDataRangePointersStream[] =
{
    PKSDATARANGE(&PinDataRangesStream[0]),
    PKSDATARANGE(&PinDataRangeAttributeList),
};

From: wdmaudiodev-bounce@xxxxxxxxxxxxx 
[mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx] On Behalf Of Matthew van Eerde
Sent: Tuesday, February 18, 2014 5:40 PM
To: wdmaudiodev@xxxxxxxxxxxxx
Subject: [wdmaudiodev] Re: IMiniportAudioSignalProcessing support in driver

For example, SlateAudioSample\micinwavetable.h:

http://code.msdn.microsoft.com/windowshardware/slate-system-virtual-audio-f241062f/sourcecode?fileId=86816&pathId=1536646987

static
PKSDATARANGE MicInPinDataRangePointersStream[] =
{
    PKSDATARANGE(&MicInPinDataRangesStream[0]),
    PKSDATARANGE(&PinDataRangeAttributeList),
};

From: wdmaudiodev-bounce@xxxxxxxxxxxxx<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx> 
[mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx] On Behalf Of Matthew van Eerde
Sent: Tuesday, February 18, 2014 5:27 PM
To: wdmaudiodev@xxxxxxxxxxxxx<mailto:wdmaudiodev@xxxxxxxxxxxxx>
Subject: [wdmaudiodev] Re: IMiniportAudioSignalProcessing support in driver

Update your kernel streaming data ranges to include the "I support modes" data 
range attribute; see SysVad for details.

From: wdmaudiodev-bounce@xxxxxxxxxxxxx<mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx> 
[mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx] On Behalf Of Jolly, David A
Sent: Tuesday, February 18, 2014 5:03 PM
To: wdmaudiodev@xxxxxxxxxxxxx<mailto:wdmaudiodev@xxxxxxxxxxxxx>
Subject: [wdmaudiodev] IMiniportAudioSignalProcessing support in driver

Hi,

I recently ran into a problem while running WHQL tests on one of our PortCls 
audio drives. Apparently, under Windows 8.1, miniports must support the 
IMiniportAudioSignalProcessing interface. So, I've gone ahead and implemented 
the IMiniportAudioSignalProcessing::GetModes routine, following the 
documentation here:  
http://msdn.microsoft.com/en-us/library/windows/hardware/dn457660(v=vs.85).aspx.
 I've also added code to the delegate routine, and inherit from the interface:


class MiniportWaveCyclic :
                public IMiniportWaveCyclic,
                public IMiniportAudioSignalProcessing,
                public IPowerNotify,
                public CUnknown {

                ...

}

...

NTSTATUS
IBTMiniportWaveCyclic::NonDelegatingQueryInterface(
                _In_ REFIID Interface,
                _COM_Outptr_ PVOID *Object
                )
{
                NTSTATUS status = STATUS_SUCCESS;

                if(!Object) {
                                status = STATUS_INVALID_PARAMETER;
                                goto exit;
                }

                ...

                else if(IsEqualGUIDAligned(Interface, 
IID_IMiniportAudioSignalProcessing)) {
                                (*Object) = 
(PVOID)(PMINIPORTAudioSignalProcessing) this;
                }

                ...

                if(*Object) {
                                ((PUNKNOWN) (*Object))->AddRef();
                }

exit:
                return status;
}

...

NTSTATUS
IBTMiniportWaveCyclic::GetModes(
                _In_ ULONG Pin,
                _Out_writes_opt_(*NumSignalProcessingModes) PGUID 
SignalProcessingModes,
                _Inout_ PULONG NumSignalProcessingModes
                )
{
                errno_t err;
                NTSTATUS status = STATUS_SUCCESS;

                if(!NumSignalProcessingModes) {
                                status = STATUS_INVALID_PARAMETER;
                                goto exit;
                }

                if(Pin > PIN_WAVE_SOURCE) {
                                status = STATUS_INVALID_PARAMETER;
                                goto complete;
                }

                // bridge pins are not supported
                if(Pin == PIN_WAVE_SOURCE) {
                                status = STATUS_NOT_SUPPORTED;
                                goto complete;
                }

                if(SignalProcessingModes) {

                                // check caller supplied buffer size
                                if((*NumSignalProcessingModes) < 
SUPPORTED_AUDIO_PROCESSING_MODES) {
                                                status = 
STATUS_BUFFER_TOO_SMALL;
                                                goto complete;
                                }

                                // copy supported processing modes
                                err = memcpy_s(
                                                SignalProcessingModes,
                                                sizeof(GUID),
                                                &AUDIO_SIGNALPROCESSINGMODE_RAW,
                                                sizeof(GUID)
                                                );

                                if(err) {
                                                status = STATUS_UNSUCCESSFUL;
                                                goto complete;
                                }
                }

complete:
                if(NT_SUCCESS(status)) {
                                (*NumSignalProcessingModes) = 
SUPPORTED_AUDIO_PROCESSING_MODES;
                } else {
                                (*NumSignalProcessingModes) = 0;
                }

exit:
                return status;
}


This appears to do the trick for passing the VerifyAudioEffectsDiscovery test 
that was failed previously. However, I can no longer stream audio through the 
endpoint. The Sound Panel simply displays a dialog box saying that the test 
sound failed to play.

I'm not sure what's wrong? Perhaps I'm missing something? The endpoint streamed 
fine prior to the inclusion of this interface. I should also note that while 
the endpoint can't be instantiated by the Sound Panel, it can be instantiated 
by KSStudio.

Any help would be greatly appreciated. Thanks,

David

Other related posts: