您的位置:首页 > 编程语言

windows编程之音频设备的捕获

2016-04-18 02:47 549 查看
#include <Windows.h>

#include <iostream>

#include <Mmdeviceapi.h>

#include <atlbase.h>

#include <strsafe.h>

#include <Audioclient.h>

#include <audiopolicy.h>

#include <Functiondiscoverykeys_devpkey.h>
using namespace std;

int TargetLatency = 60;

int TargetDurationInSec = 60;

bool UseConsoleDevice;

bool UseCommunicationsDevice;

bool UseMultimediaDevice;

wchar_t *OutputEndpoint;

template <class T> void SafeRelease(T** ppObject)

{
if (*ppObject)
{
(*ppObject)->Release();
*ppObject = NULL;
}

}

class CWASAPICapture : public IAudioSessionEvents, IMMNotificationClient

{

public:
CWASAPICapture(IMMDevice* Endpoint, bool EnableStreamSwitch,
ERole EndpointRole);
bool Initialize(UINT32 EngineLatency);
void Shutdown();
bool Start(BYTE* CaptureBuffer, size_t BufferSize);
void Stop();
WORD ChannelCount() { return _MinFormat->nChannel }

}

};

bool PickDevice(IMMDevice **DeviceToUse, bool* IsDefaultDevice, ERole *DefaultDeviceRole)

{
HRESULT hr;

bool retValue = true;
CComPtr<IMMDeviceEnumerator> deviceEnumerator = NULL;
CComPtr<IMMDeviceCollection> deviceCollection = NULL;
*IsDefaultDevice = false;   // 假定不使用默认设备
hr = deviceEnumerator.CoCreateInstance(__uuidof(MMDeviceEnumerator));
if (FAILED(hr))
{
printf("Unable to instance device enumerator!\n");
retValue = false;
goto Exit;
}
IMMDevice* device = NULL;

if (!UseCommunicationsDevice &&!UseConsoleDevice&&!UseMultimediaDevice&&OutputEndpoint == NULL)
{
hr = deviceEnumerator->EnumAudioEndpoints(eCapture, DEVICE_STATE_ACTIVE, &deviceCollection);
if (FAILED(hr))
{
printf("Unable to retrieve device collection:%x\n", hr);
retValue = false;
goto Exit;
}
printf("Select an output device:\n");
printf("0:Default Console Device\n");
printf("1:Default Communications Device\n");
printf("2:Default Multimedia Device\n");
UINT deviceCount;
hr = deviceCollection->GetCount(&deviceCount);
if (FAILED(hr))
{
printf("Unable to get device collection length\n");
retValue = false;
goto Exit;
}
for (UINT i = 0; i < deviceCount; i++)
{

LPWSTR deviceId;

IPropertyStore* property;
hr = deviceCollection->Item(i, &device);
if (FAILED(hr))
{
printf("Unable to get device %d:%x\n", i, hr);
retValue = false;
goto Exit;
}
hr = device->GetId(&deviceId);
if (FAILED(hr))
{
printf("Unable to get DeviceId %d ID:%x!\n", i, hr);
retValue = false;
goto Exit;
}
hr = device->OpenPropertyStore(STGM_READ, &property);

PROPVARIANT DeviceFriendlyName;
PropVariantInit(&DeviceFriendlyName);
hr = property->GetValue(PKEY_Device_FriendlyName, &DeviceFriendlyName);
SafeRelease(&property);
if (FAILED(hr))
{
printf("Unable to retrieve friendly name for device!\n");
retValue = false;
goto Exit;
}
wchar_t deviceName[128];
memset(deviceName, 0, sizeof(deviceName));
hr = StringCbPrintf(deviceName, sizeof(deviceName), L"%s (%s)", DeviceFriendlyName.vt != VT_LPWSTR ? L"UnKnown" : DeviceFriendlyName.pwszVal, deviceId);
wprintf(L"%s\n", deviceName);
CoTaskMemFree(deviceId);
PropVariantClear(&DeviceFriendlyName);
wchar_t
choice[10];
_getws_s(choice);
long deviceIndex;
wchar_t* endPointer;
deviceIndex = wcstoul(choice, &endPointer, 0);
if (deviceIndex == 0 && endPointer == choice)
{
printf("unrecongnized device index: %S\n", choice);
retValue = false;
goto Exit;
}
switch (deviceIndex)
{
case 0:
UseConsoleDevice = 1;
break;
case 1:
UseCommunicationsDevice = 1;
break;
case 2:
UseMultimediaDevice = 1;
break;
default:
hr = deviceCollection->Item(deviceIndex - 3, &device);
if (FAILED(hr))
{
printf("unable to retrieve %d: %x\n", deviceIndex - 3, hr);
retValue = false;
goto Exit;
}
break;
}
}
}

   else if (OutputEndpoint != NULL)

  {
 hr = deviceEnumerator->GetDevice(OutputEndpoint, &device);
 if (FAILED(hr))
 {
 printf("Unable to get endpoint for endpoint %s:%x\n", OutputEndpoint, hr);
 retValue = false;
 goto Exit;
 }

  }

  if (device == NULL)

  {
 ERole deviceRole = eConsole;
 if (UseConsoleDevice)
 {
 deviceRole = eConsole;
 }
 else if (UseCommunicationsDevice)
 {
 deviceRole = eCommunications;
 }
 else if (UseMultimediaDevice)
 {
 deviceRole = eMultimedia;
 }
 hr = deviceEnumerator->GetDefaultAudioEndpoint(eCapture, deviceRole, &device);
 if (FAILED(hr))
 {
 printf("Unable to get default device for role %d: %x\n",deviceRole,hr);
 retValue = false;
 goto Exit;
 }
 *IsDefaultDevice = true;
 *DefaultDeviceRole = deviceRole;

  }

  *DeviceToUse = device;

  retValue = true;

Exit:

return retValue;

}

int main(int argc, char* argv[])

{
int result = 0;
IMMDevice* device = NULL;
bool IsDefaultDevice;
ERole role;

printf("\n");
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (FAILED(hr))
{
printf("不能够初始化 COM: %x\n", hr);
result = hr;
goto Exit;
}
if (!PickDevice(&device, &IsDefaultDevice,&role))
{
result = -1;
goto Exit;
}
printf("Capture audio data for %d seconds\n", TargetDurationInSec);

    

Exit:
SafeRelease(&device);
CoUninitialize();
system("pause");

    return result;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: