示例#1
0
HRESULT RecordGraph::BuildGraph(CString recordFileName)
{
	HRESULT hr;
	ICreateDevEnum *pSysAudioCaptureEnum = NULL;
	hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pSysAudioCaptureEnum);
	if (FAILED(hr))
	{
		return hr;
	}

	IBaseFilter *pAudioCapture = NULL;
	IEnumMoniker *pEnumMoniker = NULL;
	hr = pSysAudioCaptureEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, &pEnumMoniker, 0);
	if (hr == S_OK)
	{
		IMoniker *pMoniker = NULL;
		ULONG fetched;
		BOOL findMicrophone = FALSE;
		while(pEnumMoniker->Next(1, &pMoniker, &fetched) == S_OK && !findMicrophone)
		{
			IPropertyBag *pPropBag;
			hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pPropBag);
			if(SUCCEEDED(hr))
			{
				VARIANT varName;
				VariantInit(&varName);
				hr = pPropBag->Read(L"FriendlyName", &varName, 0);
				if(SUCCEEDED(hr))
				{
					ASSERT(varName.vt == VT_BSTR);
					CString friendlyName(varName.bstrVal);
					if(friendlyName.Find(L"Microphone") >= 0)
					{
						hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void **)&pAudioCapture);
						findMicrophone = TRUE;
					}
					VariantClear(&varName);
					pPropBag->Release();
				}
			}
		}
		pEnumMoniker->Release();
	}
	pSysAudioCaptureEnum->Release();
	if(pAudioCapture == NULL)
	{
		return S_FALSE;
	}
	pBuilder->AddFilter(pAudioCapture, L"Audio Capture");

	IBaseFilter *pWaveDest = NULL;
	hr = CoCreateInstance(CLSID_WavDest, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pWaveDest);
	if(FAILED(hr))
	{
		return hr;
	}
	pBuilder->AddFilter(pWaveDest, L"Wave Dest");

	IBaseFilter *pFileWriter = NULL;
	hr = CoCreateInstance(CLSID_FileWriter, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pFileWriter);
	if(FAILED(hr))
	{
		return hr;
	}
	pBuilder->AddFilter(pFileWriter, L"File Writer");
	IFileSinkFilter *pFileSetter = NULL;
	hr = pFileWriter->QueryInterface(IID_IFileSinkFilter, (void **)&pFileSetter);
	if(FAILED(hr))
	{
		return hr;
	}
	AM_MEDIA_TYPE pmt;
	pmt.majortype = MEDIATYPE_Stream;
	pmt.subtype = MEDIASUBTYPE_WAVE;
	pmt.formattype = FORMAT_WaveFormatEx;
	hr = pFileSetter->SetFileName(recordFileName, &pmt);

	hr = ConnectFilters(pBuilder, pAudioCapture, pWaveDest, MEDIATYPE_NULL);if(FAILED(hr)) return hr;
	hr = ConnectFilters(pBuilder, pWaveDest, pFileWriter, MEDIATYPE_NULL);//if(FAILED(hr)) return hr;
	SaveGraphFile(pBuilder, L"D:\\Record.grf");

	pFileSetter->Release();
	pFileWriter->Release();
	pWaveDest->Release();
	pAudioCapture->Release();
}
示例#2
0
bool CKTVDlg::buildMixGraph(int filterIndex, int pinIndex)
{
    int index = -1;
    if (filterIndex != -1)
    {
        index = findFilter(&m_mixDevice, NULL, filterIndex);
    }
    else
    {
        if (GetWinVersion() >= WINVERSION_VISTA)
            index = findFilter(&m_mixDevice, L"混音");
        else
            index = findFilter(&m_mixDevice);   
    }


    if (index == -1)
        return false;

    if (pinIndex != -1)
    {
        activePin(m_mixDevice, index, NULL, pinIndex);
    }
    else
    {
        if (GetWinVersion() >= WINVERSION_VISTA)
            activePin(m_mixDevice, index);
        else
            activePin(m_mixDevice, index, L"麦克风");
    }

    SetAudioProperties(m_mixDevice);

    HRESULT r = m_mixGraphBuilder->AddFilter(m_mixDevice, L"mix Capture");
    if (FAILED(r))
        return false;

    intrusive_ptr<IPin> sourceOutPin1;
    r = GetPinByDirection(m_mixDevice, 
        reinterpret_cast<IPin**>(&sourceOutPin1), 
        PINDIR_OUTPUT);

    if (FAILED(r))
        return false;


    // {3C78B8E2-6C4D-11d1-ADE2-0000F8754B99}
    static const GUID CLSID_WavDest =
    { 0x3c78b8e2, 0x6c4d, 0x11d1, { 0xad, 0xe2, 0x0, 0x0, 0xf8, 0x75, 0x4b, 0x99 } };

    HMODULE m = LoadLibrary(L"wavdest.ax");
    if (!m)
        return false;

    typedef HRESULT (__stdcall* dllGetClassObjectProc)(const IID&, const IID&,
        void**);
    typedef HRESULT (__stdcall* dllCanUnloadNowProc)();
    do 
    {
        dllGetClassObjectProc getObjProc =
            reinterpret_cast<dllGetClassObjectProc>(GetProcAddress(
            m, "DllGetClassObject"));
        dllCanUnloadNowProc canUnloadProc =
            reinterpret_cast<dllCanUnloadNowProc>(GetProcAddress(
            m, "DllCanUnloadNow"));
        if (!getObjProc || !canUnloadProc)
            break;

        intrusive_ptr<IClassFactory> factory;
        r = getObjProc(CLSID_WavDest, IID_IClassFactory,
            reinterpret_cast<void**>(&factory));
        if (SUCCEEDED(r))
            r = factory->CreateInstance(NULL, IID_IBaseFilter, (void**)&m_aviMuxer);

        if (FAILED(r))
        {
            return false;
        }
    } while (0);


//     r = CoCreateInstance(CLSID_WavDest, NULL, CLSCTX_INPROC,
//         IID_IBaseFilter, (void **)&m_aviMuxer);
    if (FAILED(r))
        return false;

    r = m_mixGraphBuilder->AddFilter(m_aviMuxer, L"wav MUX");
    if (FAILED(r))
        return false;

    intrusive_ptr<IPin> muxerInPin;
    r = GetPinByDirection(m_aviMuxer, 
        reinterpret_cast<IPin**>(&muxerInPin), 
        PINDIR_INPUT);

    if (FAILED(r))
        return false;

    r = m_mixGraphBuilder->ConnectDirect(sourceOutPin1.get(), muxerInPin.get(), NULL);
    if (FAILED(r))
        return false;


    intrusive_ptr<IFileSinkFilter2> pFileSink;
    r = CoCreateInstance(CLSID_FileWriter, NULL, CLSCTX_INPROC, IID_IFileSinkFilter,
        (void**)&pFileSink);

    if (FAILED(r))
        return false;

    // Get the file sink interface from the File Writer
    r = pFileSink->QueryInterface(IID_IBaseFilter, (void **)&m_pFileWriter);
    if (FAILED(r))
        return false;

    // Add the FileWriter filter to the graph
    r = m_mixGraphBuilder->AddFilter((IBaseFilter *)m_pFileWriter, L"File Writer");
    if (FAILED(r))
        return false;

    intrusive_ptr<IPin> writerInPin;
    r = GetPinByDirection(m_pFileWriter, 
        reinterpret_cast<IPin**>(&writerInPin), 
        PINDIR_INPUT);
    if (FAILED(r))
        return false;

    IFileSinkFilter* fileSinkFilter;
    r = m_pFileWriter->QueryInterface(
        IID_IFileSinkFilter, reinterpret_cast<void**>(&fileSinkFilter));
    if (FAILED(r))
        return false;


    r = fileSinkFilter->SetFileName(L"D:\\1111.wav", NULL);
    if (FAILED(r))
        return false;

    intrusive_ptr<IPin> muxerOutPin;
    r = GetPinByDirection(m_aviMuxer, 
        reinterpret_cast<IPin**>(&muxerOutPin), 
        PINDIR_OUTPUT);
    if (FAILED(r))
        return false;

    r = m_mixGraphBuilder->ConnectDirect(muxerOutPin.get(), writerInPin.get(), NULL);
    if (FAILED(r))
        return false;


    return true;
}