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); 
	} 
}