⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 caudiocapturefilter2.cpp

📁 陆其明的实务精选中附带光盘中的视频聊天源代码
💻 CPP
字号:
//
// CAudioCaptureFilter2.cpp
//

#include "stdafx.h"
#include <streams.h>
#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);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -