Microsoft High Quality Voice Capture DMO

Microsoft Corporation, June 2006

System Requirements

In order to build and run this sample code, Windows Vista and Vista platform SDK (build 5456.3.0 or later) are required. Visual Studio 2005 (non-express editions) is also required, because the Vista SDK does not come with ATL header and library, which are needed for this sample code. If you already have Visual Studio 2005 installed on your system, you can use SDK to build this sample code using ATL.

1.	Open an SDK command window.
2.	Type cd %MSSDK%\Setup.
3.	Run VCIntegrate.exe.
4.	From this point forward, command windows will have the proper environment settings to build an application that takes advantage of the SDK.

Copyright and Warranty Information

THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Copyright (c) 2004-2006, Microsoft Corporation. All rights reserved.

Microsoft High Quality Voice Capture DMO Overviews

The voice capture DMO is a DirectX Media Object that provides a complete solution of high-quality audio capture on personal computers. It includes following voice signal processing components. Each component can be turned on or off individually. 
•	Acoustic echo cancellation (AEC) 
•	Microphone array processing (MicArray)
•	Noise Suppression (NS)
•	Automatic Gain Control (AGC)
•	Voice Activity Detection (VAD)

The voice capture DMO is designed to be very easy to use. The DMO has two different working modes, so called “filter mode” and “source mode” respectively. In the filter mode, the DMO works like a filter. It takes microphone (and speaker if AEC is enabled) input signals and produced output signals. In the source mode, the DMO works just like an audio source. It does not take any input signals. All the device related operations, including device initialization, audio stream capturing and synchronization, timestamp calculation and compensation, and microphone array device geometry retrieval are all handled inside of the DMO. In the source mode, applications only need to instantiate a DMO object, configure it and then retrieve echo-free or MicArray processed clean microphone signals. Therefore the source mode is much easier to use than the filter mode. 

We highly recommend using the source mode unless the filter mode is needed in some special situations. The sample code is only for the source mode, but since the voice capture DMO has a standard DMO interface, with all the property keys provided below, it is easy to implement applications using the filter mode.

Voice Capture DMO Interfaces

To use he voice capture DMO applications only need to call three interface functions to start the process and obtain outputs.

1.	Setting DMO input and output formats

In the filter mode, the DMO takes input signals and produce output signal, thus both input and output formats need to be set in the filter mode; in the source mode, the DMO does not need any input signal from applications, so only the output format need to be set. Actually, in the source mode, applications should NOT set input format; otherwise DMO may fail to process. 

In the DMO, the output format must be one of the four supported formats listed in table 1. In the filter mode, the input format can virtually be any valid uncompressed wave format. If the input format does not match the output format, the DMO will convert the format. It should be noted that currently the AEC algorithm does not support stereo or multi-channel echo cancellation. If the input speaker signal has multiple channels, all channels will be mixed down to a single channel for AEC processing. Therefore the speaker signals in different channels need to be identical. Otherwise AEC may fail to cancel the echoes.
Table 1. Allowed output formats for the voice capture DMO
	nSamplesPerSec	nChannel	nValidBitsPerSample	wFormatTag	
1	16000	1	16 	WAVE_FORMAT_PCM	
2	8000	1	16	WAVE_FORMAT_PCM	
3	11025	1	16	WAVE_FORMAT_PCM	
4	22050	1	16	WAVE_FORMAT_PCM	

The voice capture DMO accepts both WAVEFORMATEXTENSIBLE and WAVEFORMATEX formats as input/output types. And it must be an uncompressed audio format such as PCM or IEEE_FLOAT. Applications call IMediaObject::SetInputType to set input format, or IMediaObject::SetOutputType to set output format.

2.	Configuring the Voice Capture DMO

All AEC and MicArray processing parameters are passed into the DMO through PropertyStore interface. Applications can use IPropertyStore::SetValue to set the property key of the voice capture DMO. The DMO processing will be altered according to the property key values. Applications can also use IPropertyStore::GetValue to retrieve some internal processing information of the DMO. All the property keys are defined in wmcodecdsp.h. Note in followings, VBTURE is defined as (VARIANT_BOOL)-1, and VBFALSE is defined as (VARIANT_BOOL)0.

1)	MFPKEY_WMAAECMA_SYSTEM_MODE (VT_I4)
This property specifies system mode that the DMO will work on. Currently the DMO supports four system modes:

AEC only mode:	SINGLE_CHANNEL_AEC (0)
MicArray only mode:  	OPTIBEAM_ARRAY_ONLY (2)
AEC + MicArray mode:  	OPTIBEAM_ARRAY_AND_AEC (4)
No AEC or MicArray:  	SINGLE_CHANNEL_NSAGC (5)

Note that Mode 1 and 3 are reserved for future features. The DMO system mode MUST be set before starting the AEC and MicArray process. After the system mode being set, the DMO is ready to work at default settings. Internal parameters will set to optimal values for most situations, so that users do not need to worry about other details. However we do also provide users flexibility to change internal parameters through feature modes. That can be done by setting MFPKEY_WMAAECMA_FEATUREMODE_ON value to be VBTRUE.

2)	MFPKEY_WMAAECMA_DMO_SOURCE_MODE (VT_BOOL)
This property key specifies the DMO working mode. If this key is set to be true, the DMO works at source mode, otherwise it works at filter mode. In the filter mode, the DMO takes microphone input signal (and speaker input signal if AEC is enabled) and produced clean output signals, and application are responsible to capture microphone or speaker signal and send them to the DMO. In the source mode, the DMO does not take any input. All the device related operations are handled inside of the DMO. Applications only need to instantiate a DMO object, configure it and then retrieve echo-free or MicArray processed clean microphone signals. The default value for this key is VBTRUE.

Please note that under the source mode, users should only call IMediaObject::SetOutputType to set output stream format, and do NOT call IMediaObject::SetInputType to set input stream formats. Otherwise DMO initialization will fail.

3)	MFPKEY_WMAAECMA_DEVICE_INDEXES (VT_I4)
This property key specifies which audio devices to be used in the DMO source mode. The render device index is packed into the higher word of a 32-bit integer, and the capture device index is packed into the lower word of the 32-bit integer. To use system default audio devices, set the device indexes to be -1. The default value of this key is -1 (0xffffffff). The property key is only effective for the source mode.

pvDeviceId.lVal = (unsigned long)(spkDevIdx<<16) + (unsigned long)(0x0000ffff & micDevIdx);

Note that it is application’s responsibility to playback the far-end voice through the selected render device. The DMO captures the render signals after the audio mixer. If there is no active render stream on selected device, the DMO will not be able to capture any render signals and ProcessOutput method will fail. If there are multiple audio devices, the device specified for the DMO shall be the render device which is playing the audio.

4)	MFPKEY_WMAAECMA_FEATURE_MODE (VT_BOOL)
This property key turns the feature mode on/off. Setting this property key’s value to VBTURE will enable user to change some internal parameters of the AEC and MicArray algorithms. The default value of this key is VBFALSE.

The feature mode must be turned on for following property keys to take effective. 

5)	MFPKEY_WMAAECMA_FEATR_FRAME_SIZE (VT_I4)
This property key specifies the frame size of AEC processing. AEC processes PCM samples frame by frame. The value of this property is the length of the frame. AEC supports frame size of 80, 128, 160, 240, 256, and 320. If this key is set to be 0, an optimal frame size will be determined automatically by the DMO according to the system mode and output format. It is recommended to let the DMO determine the frame size, which is also the default behavior. 

This property key is bi-directional. Users can always retrieve the actual frame size being used through this property after AllocateStreamingResources() method is called, or after the first time ProcessOutput() is called, even when feature mode is off. 

6)	MFPKEY_WMAAECMA_FEATR_ECHO_LENGTH (VT_I4)
This property key controls the length of echo that can be handled by AEC. The AEC algorithm relies on an adaptive filter to find the room responses and cancel the echo, so the filter length is determined by echo lengths. Although more flexible echo lengths are supported, it is suggested to use one of the following values: 128, 256, 512 and 1024 in the units of milliseconds. The default value is 256 ms, which are long enough for most office and home environments. This property is effective only when AEC is enabled.

7)	MFPKEY_WMAAECMA_FEATR_NS (VT_I4)
This property turns noise suppression on/off. Noise suppression is a DSP component to suppress or reduce the stationary background noise in the audio signal. Allowed values are 0 (off) or 1 (on). The default value is 1.

8)	MFPKEY_WMAAECMA_ FEATR _AGC (VT_BOOL) 
This property turns digital AGC on/off. AGC is a DSP component to automatically adjust the digital gain of the output, so that the output signal is always around a certain level. Allowed values are VBTRUE (on) or VBFALSE (off). The default value of this key is VBFALSE.

9)	MFPKEY_WMAAECMA_FEATR_AES (VT_I4)
This property key specifies how many times the AES (Acoustic Echo Suppression) process will be applied on the residual signal after AEC. AES can further suppress echo residuals. The valid values are 0, 1, and 2. The default value is 0. This property key is only effective when AEC is enabled.

10)	MFPKEY_WMAAECMA_FEATR_VAD (VT_I4)
This property key specifies mode of voice activity detection (VAD). It can be 
•	AEC_VAD_DISABLED – VAD is disabled
•	AEC_VAD_NORMAL: for general purpose. The output is range from 0 to 3 as indicated below. This VAD classification has balanced false detection rate and miss detection rate. The output of VAD result can be
          0 - non-speech
          1 - voiced speech
          2 - unvoiced speech
          3 - mixed speech (mixture of voiced and unvoiced speech)
•	AEC_VAD_FOR_AGC: this VAD information can be used for AGC and noise suppression purpose. The result is binary (0 or 1) to indicates voiced speech only, because the energy of the speech is mainly from voiced sound. The threshold is higher than normal mode to reduce the false detection rate.
•	AEC_VAD_FOR_SILENCE_SUPPRESION: this VAD information can be used for silence suppression. The result is binary (0 or 1) to indicated voice activity regardless the difference of voiced or unvoiced speech. Note there is 1 second tailing period for voice.

Because the DMO output may contains multiple frames, the VAD results cannot be retrieved through a property key. Instead, the VAD results are coded into the output signals. The lowest bits of the first two samples in each frame are used to code VAD results. To decode the VAD results, write a simple function like below.

int AecDecodeVAD(short *pMicOut)
{
    int iVAD = (*pMicOut) & 0x01;
    pMicOut ++;
    iVAD |= (*pMicOut<<1) & 0x02;
    return iVAD;
}

11)	MFPKEY_WMAAECMA_FEATR_CENTER_CLIP (VT_BOOL) 
This property turns center clipping on/off. There are usually some echo residues after the echo cancellation processing. Center clipping is a process to completely remove the echo residuals. Allowed values are VBTRUE (on) or VBFALSE (off). The default value is VBTRUE. This property key is effective only when AEC is enabled.

12)	MFPKEY_WMAAECMA_FEATR_NOISE_FILL (VT_BOOL) 
This property turns noise filling on/off. After center clipping removes echo residuals, it is better to fill the silence with comfort noise for better user experience. Allowed values are VBTRUE (on) or VBFALSE (off). The default value is VBTRUE. This property key is effective only when AEC is enabled.

13)	MFPKEY_WMAAECMA_RETRIEVE_TS_STATS (VT_BOOL) (AEC)
This property enables or disables saving/retrieving timestamp statistics in/from a registry key. Timestamp accuracy of capture and render streams is crucial in the AEC algorithms. In reality, timestamps are often imperfect with noise and relative drifting between render and capture stream. For different audio devices, timestamp may have different statistics, i.e. drifting rate and variance. In the DMO, when AEC is enabled, imperfect timestamps are processed and compensated according to these statistics. If they are known when the DMO starts, the timestamp processing and compensation can be more efficient. Therefore, if the property key is set to be VBTRUE, timestamps statistics will be save into a registry key and retrieved at next time the DMO starts. The default value of this key is VBFALSE.  This property key is effective only when AEC is enabled.

See also MFPKEY_WMAAECMA_DEVICEPAIR_GUID.

14)	MFPKEY_WMAAECMA_QUALITY_METRICS (VT_BLOB)
This property can be used to retrieve AEC quality metrics. The AEC quality metric structure is defined in wmcodecdsp.h. Much internal AEC processing information can be accessed through the quality metric structure and used for runtime AEC quality evaluation. This property key is effective only when AEC is enabled.

// AEC quality metric structure
typedef struct tagAecQualityMetrics_Struct
{
    LONGLONG i64Timestamp;  // Timestamp when the quality metrics are collected
    BYTE  ConvergenceFlag;  // AEC convergence flag
    BYTE  MicClippedFlag;   // Mic input signal clipped
    BYTE  MicSilenceFlag;   // Mic input too quiet or silent
    BYTE  PstvFeadbackFlag; // Positive feadbacks causing chirping sound
    BYTE  SpkClippedFlag;   // Speaker input signal clipped
    BYTE  SpkMuteFlag;      // Speaker muted or too quiet
    BYTE  GlitchFlag;       // Glitch flag
    BYTE  DoubleTalkFlag;   // Double talk flag
    ULONG uGlitchCount;     // Glich count
    ULONG uMicClipCount;    // Mic clipping count
    float fDuration;        // AEC running duration
    float fTSVariance;      // Timestamp variance (long-term average)
    float fTSDriftRate;     // Timestamp drifting rate (long-term average)
    float fVoiceLevel;      // Near-end voice level after AEC (short-term smoothed)
    float fNoiseLevel;      // Noise level of mic input signals (long-term smoothed)
    float fERLE;            // Echo return loss enhancement (short-term smoothed)
    float fAvgERLE;         // Average ERLE over whole running duration
    DWORD dwReserved;       // reserved
}AecQualityMetrics_Struct;

15)	MFPKEY_WMAAECMA_MICARRAY_DESCPTR (VT_BLOB)
This property can be used to send the microphone array geometry information to the DMO. The microphone geometry structures as listed below are defined in ksmedia.h. This property key is effective only when MicArray processing is enabled.
KSAUDIO_MIC_ARRAY_GEOMETRY
KSAUDIO_MICROPHONE_COORDINATES
KSMICARRAY_MICTYPE

Note that setting microphone array geometry is only effective for the filter mode. In the source mode, the DMO will query the geometry information through the microphone array device driver (the device must be a USB device).

16)	MFPKEY_WMAAECMA_DEVICEPAIR_GUID (VT_CLSID)
This property key is related MFPKEY_WMAAECMA_RETRIEVE_TS_STATS. Since each different combination of capture/render pair may have different timestamp statistics. To separate them, each device pair should have a unique key to save the statistics. So this property key can be used to assign a GUID to each device pair.

Note this property is only effective for the filter mode when AEC is enabled. In the DMO source mode, a GUID will be generated automatically based on audio devices selected by MFPKEY_WMAAECMA_DEVICE_INDEXES

17)	MFPKEY_WMAAECMA_FEATR_MICARR_MODE (VT_I4)
This property key specifies microphone array processing mode. This property key is effective only when MicArray processing is enabled. The key value can be
•	MICARRAY_SINGLE_CHAN (0x0000),  Use one single channel. Last 8 bits specify which channel to use
•	MICARRAY_SIMPLE_SUM (0x0100),  Simply sum all channels 
•	MICARRAY_SINGLE_BEAM (0x0200),  Perform beam forming. Beam selected by internal source localizer
•	MICARRAY_FIXED_BEAM (0x0400),  Perform beam forming. Always select the center beam
•	MICARRAY_EXTERN_BEAM (0x0800),  Perform beam forming. Beam selected externally by applications

The default mode is MICARRAY_SINGLE_BEAM (0x0200).

18)	MFPKEY_WMAAECMA_FEATR_MICARR_BEAM (VT_I4) 
The fundamental processing for microphone array is beam forming. So it is important how the beams are defined and labeled. For all five pre-defined geometries, there are 11 beams from -50 degree to 50 degree horizontally with 10 degree apart in between. For convenience, these 11 beams are labeled with number 0 to 10, where 0 is for the beam at -50 degree and 10 is for the beam at 50 degree. This property key is effective only when MicArray processing is enabled. The default value is 5 (center beam at 0 dgree).

This property key is bi-directional. If the microphone array processing mode is MICARRAY_SINGLE_BEAM, then this key can be used to retrieve the beam number selected by internal source localizer. If the processing mode is MICARRAY_EXTERN_BEAM, then this key can be used to set the beam number selected by applications. 

19)	MFPKEY_WMAAECMA_FEATR_MICARR_PREPROC (VT_BOOL)
This property key turns on/off for microphone array pre-processing, which can remove stationary tonal interferences, for example a fixed pitch tone. This property key is effective only when MicArray processing is enabled.

20)	MFPKEY_WMAAECMA_MIC_GAIN_BOUNDER (VT_BOOL)
This property turns microphone gain bounder (MBG) on/off. If microphone gain is too high, the captured signal will saturates and be clipped, which is a non-linear effect and will cause AEC to fail. On the other hand, if the microphone gain is too low, then the signal to noise ratio is very low; AEC will not work well either. The MGB is to ensure the microphone gain is in a proper level. The default value is VBTURE.

Note MGB is only available for source mode DMO. For filter mode DMO, it is applications responsibility to set proper microphone gain level.

3.	Processing and Obtaining DMO Outputs

Application can simply retrieve the DMO outputs by calling IMediaObject::ProcessOutput. Application must keep calling ProcessOutput method until DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE buffer flag is cleared.

Note that all format and compatibility checks are done when the ProcessOutput is called at the first time. For example, if MicArray+AEC mode is set, but there is no MicArray device present, then ProcessOutput will return with errors.

How to Write Voice Capture Applications
1.	Instantiating a Voice Capture DMO

The voice capture DMO (MFWMADMO.DLL) is already registered in Windows Vista. Application can instantiate a DMO object by calling the CoCreateInstance COM function. The application must pass the class identifier of the DMO, and the interface identifier of IMediaObject, along with a pointer to an IMediaObject pointer. Then, a handle to IPropertyStore interface can be obtained for the DMO so that the DMO can be configured. 

IUnknown* pUnk = NULL;
IMediaObject* pDMO = NULL;    
IPropertyStore* pPS = NULL;
CHECKHR(CoCreateInstance(CLSID_CWMAudioAEC, NULL, CLSCTX_INPROC_SERVER, IID_IMediaObject, (void**)&pDMO));
CHECKHR(pDMO->QueryInterface(IID_IPropertyStore, (void**)&pPS));

2.	Configuring the Voice Capture DMO
2.1.	Configure DMO system mode

In order to configure voice capture DMO system mode, application should call IProperty::SetValue to set corresponding property keys. An example of setting DMO system mode is given below. Please refer to the last section for details of other property keys. 

// Set AEC-MicArray system mode
LONG system_mode = SINGLE_CHANNEL_AEC; // AEC only mode
    PROPVARIANT pvSysMode;
    PropVariantInit(&pvSysMode);
    pvSysMode.vt = VT_I4;
    pvSysMode.lVal = (LONG)(system_mode);
    CHECKHR(pPS->SetValue(MFPKEY_WMAAECMA_SYSTEM_MODE, &pvSysMode));
    CHECKHR(pPS->GetValue(MFPKEY_WMAAECMA_SYSTEM_MODE, &pvSysMode));
    PropVariantClear(&pvSysMode);

2.2.	Set DMO output format

Applications should call IMediaObject::SetInputType to set the DMO output format.

DMO_MEDIA_TYPE mt;
// set output format as 16k 16-bit PCM
WAVEFORMATEX wfxOut = {WAVE_FORMAT_PCM, 1, 16000, 32000, 2, 16, 0};

    hr = MoInitMediaType(&mt, sizeof(WAVEFORMATEX));
    CHECK_RET(hr, "MoInitMediaType failed");
    
    mt.majortype = MEDIATYPE_Audio;
    mt.subtype = MEDIASUBTYPE_PCM;
    mt.lSampleSize = 0;
    mt.bFixedSizeSamples = TRUE;
    mt.bTemporalCompression = FALSE;
    mt.formattype = FORMAT_WaveFormatEx;
    memcpy(mt.pbFormat, &wfxOut, sizeof(WAVEFORMATEX));
    
    hr = pDMO->SetOutputType(0, &mt, 0); 
    CHECK_RET(hr, "SetOutputType failed");
    MoFreeMediaType(&mt);

3.	Call DMO Processing and Retrieve Outputs

Applications then call IMediaObject::ProcessOutput to obtain outputs. Application should keep calling ProcessOutput as long as there are still samples in the output buffer, which is indicated by DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE bit in the buffer status word. However, application should implement IMediaBuffer interface and create a DMO output buffer object first. An example of implementation is provided in the sample code (mediabuf.h). 

// allocate 1 second output buffer. Since the process thread is waked up for every
// 10 ms, normally the application will get 10 ms data each time. Allocating a 
// larger buffer helps to reduce occasional glitches caused by system being busy.
    LONG cOutputBufLen = wfxOut.nSamplesPerSec * wfxOut.nBlockAlign;
    BYTE *pbOutputBuffer = new BYTE[cOutputBufLen];
    CHECK_ALLOC (pbOutputBuffer, "out of memory.\n");

// Create a DMO output buffer object (CBaseMediaBuffer defined in mediabuf.h)
class CStaticMediaBuffer : public CBaseMediaBuffer {
public:
    STDMETHODIMP_(ULONG) AddRef() {return 2;}
    STDMETHODIMP_(ULONG) Release() {return 1;}
    void Init(BYTE *pData, ULONG ulSize, ULONG ulData) {
        m_pData = pData;
        m_ulSize = ulSize;
        m_ulData = ulData;
    }
};
CStaticMediaBuffer outputBuffer; 
DMO_OUTPUT_DATA_BUFFER OutputBufferStruct = {0};
OutputBufferStruct.pBuffer = &outputBuffer;

// main loop to get microphone output from the DMO
ULONG cbProduced = 0;
    while (1)
    {
        Sleep(10); //sleep 10ms
        do{
            outputBuffer.Init((byte*)pbOutputBuffer, cOutputBufLen, 0);
            OutputBufferStruct.dwStatus = 0;
            hr = pDMO->ProcessOutput(0, 1, &OutputBufferStruct, &dwStatus);
            CHECK_RET (hr, "ProcessOutput failed");

            if (hr == S_FALSE) {
                cbProduced = 0;
            } else {
                hr = outputBuffer.GetBufferAndLength(NULL, &cbProduced);
                CHECK_RET (hr, "GetBufferAndLength failed");
            }

            // write mic output data into a file using PCM format  
            if (fwrite(pbOutputBuffer, 1, cbProduced, pfMicOutPCM) != cbProduced) 
            { 
                puts("write error"); 
                goto exit; 
            }
        } while (OutputBufferStruct.dwStatus & DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE);
    }

4.	Release the Voice Capture DMO

After the whole process is finished, application should release the DMO at the end.
    // Cleanup resources
    if (pDMO)
    {
       pDMO->Release();
       pDMO = NULL;
    }
    if (pPs)
    {
       pPs->Release();
       pPs = NULL;
    }

How to Run the Demo Application

If you build the demo application successfully, you will get an executable file AecSDKDemo.exe. To run it, type “AecSDKDemo” in a command window followed by required or optional arguments as described below.

AecSDKDemo -out mic_out.pcm -mod system_mode [-option value]

Required arguments:
    -out  - Specifies output file name
    -mod  - Specifies voice capture system mode. Refer to “Configuring the voice capture DMO” section for details.

Optional arguments: 
    -feat – Turns feature mode on (1) or off (0)
    -ns   - Turns noise suppression on (1) or off (0). Feature mode must be on for specifying this.
    -agc  - Turns digital AGC on (1) or off (0). Feature mode must be on for specifying this.
    -cntrclip  - Turns center clipping on (1) or off (0). Feature mode must be on for specifying this.
    -spkdev – Specifies speaker device index. If not specified, the user will be asked to select.
    -micdev – Specifies microphone device index. If not specified, the user will be asked to select. 
    -duration – Specifies how long the application runs.

Note that this demo application does not playback any signals. To run the demo properly for AEC enabled modes (mode 0 and 4), users must playback some audio signals through the same speaker device specified for the DMO (i.e. the device specified by "-spkdev" option), which simulates the far-end voice in a two-way chatting scenario. Users may use any player to play any audio signals. If there is no active render stream on the selected speaker device, the DMO will fail to process.

Special Notes for Microphone Array:

1.	Customized geometry support
	Currently, only five predefined geometries are supported, two for 2-element arrays and other three for 4-element arrays. As the first effort of integrating microphone array technology into the operating system, we think these five geometries will cover most common scenarios for microphone array applications. Please refer to the microphone array document at http://www.microsoft.com/whdc/device/audio/MicArrays.mspx  for details. However, we will be continuing to provide the best microphone array technology in class. Based on user feedbacks more geometries or a more flexible way to add customized geometries will be provided in feature.

2.	Flexibility of the microphone array geometries
To ensure the best quality, we recommend using one of five predefined geometries. However, the geometries can be relaxed at some level without substantial quality degradation. There are two predefined 2-element geometries with a distance of 100mm and 200mm, respectively, between the two elements. For the 100mm geometry, the actual distance can be 75mm to 150mm; and for the 200mm geometry, the actual distance can be 150mm to 270mm. However, the 4-element geometries need to be followed more strictly. In general speaking, no more than 10mm variation of distances for 4-element geometries will not hurt the quality substantially.

3.	Microphone array devices with Intel® High Definition Audio interface
Currently, we fully support microphone array devices with USB interface only. Please refer to a guide at http://www.microsoft.com/whdc/device/audio/MicArrays_guide.mspx for more details. 

Using USB interface is mainly for the convenience of retrieving geometry information directly through the driver. The Microsoft class USB audio driver can retrieve the geometry from the device firmware. So applications can call IKsControl::KSProperty with a property ID KSPROPERTY_AUDIO_MIC_ARRAY_GEOMETRY to retrieve the geometry for the driver. Because using IKsControl::KSProperty is the only way for the DMO to retrieve the geometry, if the application wants to use the source mode DMO, the driver must be able to support KSPROPERTY_AUDIO_MIC_ARRAY_GEOMETRY property set. The Microsoft class HD-Audio driver does not support this because there is not an easy way to know the microphone geometry unless the geometry is fixed, for example on a laptop computer.

So there are two ways to use a microphone array device with HD-Audio interface. 
1.	If the device uses a third-party driver instead of the class driver and the third-party driver supports KSPROPERTY_AUDIO_MIC_ARRAY_GEOMETRY property set, then application can still use the source mode DMO.
2.	If the device uses the class drivers, or a third-party driver that does not support KSPROPERTY_AUDIO_MIC_ARRAY_GEOMETRY property set, then the DMO will not be able to retrieve the array geometry. Application must use the filter mode DMO and send the geometry information to the DMO. Please be noted that in the filter mode application need send both microphone capture signal and speaker render signal to the DMO for processing.