Exposing Hardware-Accelerated Capture Effects

In Windows XP and later, the WDM audio framework supports hardware acceleration of audio-capture effects that are exposed through DirectSound. These effects include acoustic echo cancellation (AEC) and noise suppression (NS). For information about how a DirectSoundCapture application enables use of hardware-accelerated AEC and NS, see the Microsoft Windows SDK documentation.

A miniport driver can expose hardware acceleration for any subset of these effects, depending on the capabilities of the underlying device. To expose the hardware's capabilities for AEC and NS effects, each pin on the AEC filter that the driver implements should meet these requirements:

The specific requirements for exposing hardware-accelerated AEC and NS nodes are presented below.

Acoustic Echo Cancellation

A PCM miniport driver exposes hardware support for AEC in the form of a topology for both the capture and render streams that meets this additional requirement:

  • The pin must include an AEC node (KSNODETYPE_ACOUSTIC_ECHO_CANCEL), which must be specified in its proper position in the ordered node chain (see below).

Noise Suppression

A PCM miniport driver exposes hardware support for NS in the form of a topology for the capture stream that meets this additional requirement:

  • The pin must include an NS node (KSNODETYPE_NOISE_SUPPRESS), which must be specified in its proper position in the ordered node chain (see below).

Node-Chain Ordering

Currently, the DirectSound capture-effects architecture requires that the nodes be specified in the order in which they are requested by the application. As a result, the order in which the miniport driver specifies its nodes must match the order that is used by the AEC system filter (Aec.sys), which implements the AEC and NS algorithms in software.

To enable hardware acceleration, the driver must specify the effects that are implemented by the hardware in the following order:

KSNODETYPE_ADC

KSNODETYPE_ACOUSTIC_ECHO_CANCEL

KSNODETYPE_NOISE_SUPPRESS

Note that this list can omit any unimplemented effects as long as the relative ordering is preserved.

AEC Node Pin Assignments

An adapter driver uses an array of PCCONNECTION_DESCRIPTOR structures to specify the connections within a filter. Each array element describes one connection, which can be node-to-node, node-to-pin, or pin-to-pin. For details, see Nodes and Connections.

To use the PCCONNECTION_DESCRIPTOR structure, the driver writer assigns "logical" pins to nodes. These are "pins" on the nodes themselves and are used solely to specify the connections inside the filter. This is in contrast to the external pins on the filter, which are used to connect to other filters.

The following table shows the pin IDs that the adapter driver should assign to the four logical pins on the AEC node.

Pin ID Parameter Name Value Meaning

KSNODEPIN_AEC_RENDER_IN

1

Sink pin (node input) for render stream

KSNODEPIN_AEC_RENDER_OUT

0

Source pin (node output) for render stream

KSNODEPIN_AEC_CAPTURE_IN

2

Sink pin (node input) for capture stream

KSNODEPIN_AEC_CAPTURE_OUT

3

Source pin (node output) for capture stream

The pin IDs in the preceding table are defined in the header file Ksmedia.h.

The following code example shows how an adapter driver can specify the internal topology of an AEC filter that contains both an AEC node and an NS node:

    // AEC Filter Topology

    // Pin IDs for external pins on AEC filter
    #define ID_CaptureOutPin   0   // microphone stream
    #define ID_CaptureInPin    1
    #define ID_RenderOutPin    2   // speaker stream
    #define ID_RenderInPin     3

    // Generic pin IDs for simple node with one input and one output
    #define NODE_INPUT_PIN     1
    #define NODE_OUTPUT_PIN    0

    // Node IDs
    #define NODE_ID_AEC        0   // acoustic echo cancellation
    #define NODE_ID_NS         1   // noise suppression

    // The array below defines the internal topology of an
    // AEC filter that contains an AEC node and an NS node.

    const PCCONNECTION_DESCRIPTOR AecConnections[] = {
        { PCFILTER_NODE, ID_RenderInPin,       NODE_ID_AEC,    KSNODEPIN_AEC_RENDER_IN  },
        { NODE_ID_AEC,   KSNODEPIN_AEC_RENDER_OUT,   PCFILTER_NODE,  ID_RenderOutPin    },
        { PCFILTER_NODE, ID_CaptureInPin,      NODE_ID_AEC,    KSNODEPIN_AEC_CAPTURE_IN },
        { NODE_ID_AEC,   KSNODEPIN_AEC_CAPTURE_OUT,  NODE_ID_NS,     NODE_INPUT_PIN     },
        { NODE_ID_NS,    NODE_OUTPUT_PIN,      PCFILTER_NODE,  ID_CaptureOutPin   }
    };

The AecConnections array in the preceding code example defines the filter topology that is shown in the following figure.

Diagram illustrating the internal topology of an AEC filter with AEC and NS nodes.

The preceding figure represents each connection inside the filter with a dashed arrow that points in the direction of data flow. A total of five connections appear in the figure. Each connection corresponds to one of the five elements in the AecConnections array in the code example.