www.pudn.com > AVChat1.rar > CAudioCaptureFilter2.cpp
// // CAudioCaptureFilter2.cpp // #include "stdafx.h" #include#include "CAudioCaptureFilter2.h" #include "UDsUtils.h" #include "UFilterUtils.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif //////////////////////////////////////////////////////////////////////// CAudioCaptureFilter2::CAudioCaptureFilter2(IGraphBuilder * inGraph) : CDXFilter(inGraph, GUID_NULL, "Audio Capture") { mDevice = NULL; } CAudioCaptureFilter2::~CAudioCaptureFilter2(void) { mInputList.RemoveAll(); } void CAudioCaptureFilter2::SetDevice(CAVDevice * inDevice) { mDevice = inDevice; } BOOL CAudioCaptureFilter2::CreateFilter(void) { if (mFilter) { return TRUE; } ASSERT(mDevice); if (mGraph) { mFilter = UDsUtils::CreateAudioDevice(*mDevice); if (mFilter) { if (SUCCEEDED(mGraph->AddFilter(mFilter, mName))) { BuildInputList(); SetDefaultInputPin(); // SetCaptureBufferSize(); return TRUE; } } } ReleaseFilter(); return FALSE; } // Set microphone as default input void CAudioCaptureFilter2::SetDefaultInputPin(void) { IEnumPins * pinEnum = NULL; if (SUCCEEDED(mFilter->EnumPins(&pinEnum))) { pinEnum->Reset(); IPin * pin = NULL; ULONG fetchCount = 0; BOOL found = FALSE; while (!found && SUCCEEDED(pinEnum->Next(1, &pin, &fetchCount)) && fetchCount) { if (pin) { PIN_INFO pinInfo; if (SUCCEEDED(pin->QueryPinInfo(&pinInfo))) { pinInfo.pFilter->Release(); if (pinInfo.dir == PINDIR_INPUT) { char szName[128]; ::WideCharToMultiByte(CP_ACP, 0, pinInfo.achName, -1, szName, 128, NULL, NULL); CString pinName = szName; pinName.MakeLower(); if (pinName.Find("mic", 0) >= 0) { found = TRUE; } // Enable this found pin if (found) { IAMAudioInputMixer * pMixer = GetMixer(pin); pMixer->put_Enable(TRUE); pMixer->put_MixLevel(1.0); // Save the connector index mDevice->SetAudioConnector(GetConnector()); } } } pin->Release(); } } pinEnum->Release(); // If line-in not found, set the first input item if (!found) { SetConnector(0); } } } void CAudioCaptureFilter2::SetCaptureBufferSize(void) { IPin * pCapturePin = GetPin(FALSE); if (pCapturePin) { DWORD dwBytesPerSec = 0; DWORD dwLatencyInMilliseconds = 250;//40; // Query the current media type used by the capture output pin AM_MEDIA_TYPE * pmt = {0}; IAMStreamConfig * pCfg = NULL; HRESULT hr = pCapturePin->QueryInterface(IID_IAMStreamConfig, (void **)&pCfg); if (SUCCEEDED(hr)) { hr = pCfg->GetFormat(&pmt); if (SUCCEEDED(hr)) { // Fill in values for the new format WAVEFORMATEX *pWF = (WAVEFORMATEX *) pmt->pbFormat; dwBytesPerSec = pWF->nAvgBytesPerSec; DeleteMediaType(pmt); } pCfg->Release(); } if (dwBytesPerSec) { IAMBufferNegotiation * pNeg = NULL; hr = pCapturePin->QueryInterface(IID_IAMBufferNegotiation, (void **)&pNeg); if (SUCCEEDED(hr)) { ALLOCATOR_PROPERTIES AllocProp; AllocProp.cbAlign = -1; // -1 means no preference. AllocProp.cbBuffer = dwBytesPerSec * dwLatencyInMilliseconds / 1000; AllocProp.cbPrefix = -1; AllocProp.cBuffers = -1; hr = pNeg->SuggestAllocatorProperties(&AllocProp); pNeg->Release(); } } } } void CAudioCaptureFilter2::BuildInputList(void) { mInputList.RemoveAll(); if (mFilter) { IEnumPins * pinEnum = NULL; if (SUCCEEDED(mFilter->EnumPins(&pinEnum))) { pinEnum->Reset(); BOOL pass = TRUE; IPin * pin = NULL; ULONG fetchCount = 0; while (pass && SUCCEEDED(pinEnum->Next(1, &pin, &fetchCount)) && fetchCount) { if (pin) { PIN_INFO pinInfo; if (SUCCEEDED(pin->QueryPinInfo(&pinInfo))) { pinInfo.pFilter->Release(); if (pinInfo.dir == PINDIR_INPUT) { char pinName[128]; ::WideCharToMultiByte(CP_ACP, 0, pinInfo.achName, -1, pinName, 128, NULL, NULL); CAudioInput inputItem; inputItem.mInputName = pinName; inputItem.mInputPin = pin; mInputList.AddTail(inputItem); } } pin->Release(); pin = NULL; } else { pass = FALSE; } } pinEnum->Release(); } } } long CAudioCaptureFilter2::GetConnectorCount(void) { int inputCount = 0; int outputCount = 0; UFilterUtils::GetPinCount(mFilter, inputCount, outputCount); return inputCount; } CString CAudioCaptureFilter2::GetConnectorName(long inIndex) { long index = inIndex; POSITION pos = mInputList.GetHeadPosition(); while (pos && index > 0) { mInputList.GetNext(pos); index--; } CString connector = ""; if (pos) { CAudioInput inputItem = mInputList.GetNext(pos); connector = inputItem.mInputName; } return connector; } void CAudioCaptureFilter2::SetConnector(long inIndex) { if (inIndex >= 0 && inIndex < mInputList.GetCount()) { long index = inIndex; POSITION pos = mInputList.GetHeadPosition(); while (pos && index > 0) { mInputList.GetNext(pos); index--; } if (pos) { CAudioInput inputItem = mInputList.GetNext(pos); IAMAudioInputMixer * pMixer = GetMixer(inputItem.mInputPin); pMixer->put_Enable(TRUE); pMixer->put_MixLevel(AMF_AUTOMATICGAIN); } } } long CAudioCaptureFilter2::GetConnector(void) { long index = 0; BOOL enabled = FALSE; POSITION pos = mInputList.GetHeadPosition(); while (pos && !enabled) { CAudioInput inputItem = mInputList.GetNext(pos); IAMAudioInputMixer * pMixer = GetMixer(inputItem.mInputPin); pMixer->get_Enable(&enabled); index++; } return (index - 1); } IAMAudioInputMixer * CAudioCaptureFilter2::GetMixer(IPin * inPin) { IAMAudioInputMixer * pMixer = NULL; inPin->QueryInterface(IID_IAMAudioInputMixer, (void**) &pMixer); if (pMixer) { pMixer->Release(); } return pMixer; } // Set mix level for all input pins void CAudioCaptureFilter2::SetMixLevel(double inLevel) { POSITION pos = mInputList.GetHeadPosition(); while (pos) { CAudioInput inputItem = mInputList.GetNext(pos); IAMAudioInputMixer * pMixer = GetMixer(inputItem.mInputPin); pMixer->put_MixLevel(inLevel); } }