📄 caudiocapturefilter2.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 + -