Here is the C++ code:
#include <atlbase.h>
#include <atlimage.h>
#include <Dshow.h>
#pragma comment(lib, "Strmiids.lib")
#include "Qedit.h"
void init_capture();
CComPtr<IGraphBuilder> pGraph; CComPtr<ICaptureGraphBuilder2> pBuild;
CComPtr<IBaseFilter> pCapture; CComPtr<IBaseFilter> pAudioRenderer;
CComPtr<ICreateDevEnum> pDevEnum;
CComPtr<IEnumMoniker> pEnum;
CComPtr<IMoniker> pMoniker;
CComPtr<IMediaControl> pMediaControl;
CComPtr<IMediaEventEx> pEvent;
CComPtr<IBaseFilter> pAudioGrabberF;
CComPtr<ISampleGrabber> pAudioGrabber;
void CCapture_Audio_MFCDlg::init_capture()
{
HWND parameter_hwnd = m_hWnd;
HRESULT hr;
{
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&pBuild );
if (SUCCEEDED(hr))
{
hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraph);
if (SUCCEEDED(hr))
{
pBuild->SetFiltergraph(pGraph);
hr = CoCreateInstance(CLSID_SystemDeviceEnum, 0, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (LPVOID*)&pDevEnum);
if(SUCCEEDED(hr))
{
hr = pDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, &pEnum, 0);
if(SUCCEEDED(hr))
{
if( pEnum->Next(1, &pMoniker,0) == S_OK )
{
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void **)&pCapture);
if(SUCCEEDED(hr))
{
pGraph->AddFilter(pCapture, L"Capture Filter");
hr = CoCreateInstance(CLSID_AudioRender, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&pAudioRenderer);
if (SUCCEEDED(hr))
{
pGraph->AddFilter(pAudioRenderer, L"Audio Renderer Filter");
hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pAudioGrabberF));
if (SUCCEEDED(hr))
{
hr = pGraph->AddFilter(pAudioGrabberF, L"Sample Grabber");
if (SUCCEEDED(hr))
{
hr = pAudioGrabberF->QueryInterface(IID_ISampleGrabber, (void**)&pAudioGrabber);
if (SUCCEEDED(hr))
{
AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(mt));
mt.majortype = MEDIATYPE_Audio;
mt.subtype = MEDIASUBTYPE_PCM;
hr = pAudioGrabber->SetMediaType(&mt);
if (SUCCEEDED(hr))
{
hr = pAudioGrabber->SetOneShot(TRUE);
if (SUCCEEDED(hr))
{
hr = pAudioGrabber->SetBufferSamples(TRUE);
if (SUCCEEDED(hr))
{
hr = pBuild->RenderStream(NULL, NULL, pCapture, pAudioGrabberF, pAudioRenderer);
HWND hWnd = parameter_hwnd;
hr = pGraph->QueryInterface(IID_IMediaEventEx, (void **)&pEvent);
hr = pEvent->SetNotifyWindow((OAHWND)hWnd, 0, 0);
hr = pGraph->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
hr = pMediaControl->Run();
SaveGraphFile(pGraph, L"c:\\temp\\audio_capture.grf");
}
}
}
_FreeMediaType(mt);
}
}
}
}
}
}
}
}
}
}
}
}
Audio Capture does not work in the MFC application but works in GraphStudioNext.
Code with
hr = pBuild->RenderStream(NULL, NULL, pCapture, NULL, pAudioRenderer);
instead of
hr = pBuild->RenderStream(NULL, NULL, pCapture, pAudioGrabberF, pAudioRenderer);
works both in the application and in GraphStudioNext.
So with samplagrabber does not work.
init_capture(); is called in
BOOL CCapture_Audio_MFCDlg::OnInitDialog()
void _FreeMediaType(AM_MEDIA_TYPE& mt)
{
if (mt.cbFormat != 0)
{
CoTaskMemFree((PVOID)mt.pbFormat);
mt.cbFormat = 0;
mt.pbFormat = NULL;
}
if (mt.pUnk != NULL)
{
mt.pUnk->Release();
mt.pUnk = NULL;
}
}
What is wrong in the code?