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;
}
#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;
}
相关文章推荐
- windows界面编程之自绘窗体(模仿腾讯qq)
- windows内核编程之如何防止一个相同的程序重复运行
- windows界面编程之自绘菜单
- c/c++实现浏览器的下载功能
- PHP基础算法
- 让PHP开发者事半功倍的十大技巧
- C++输出全排列递归算法详细解释
- PLC梯形图编程练习
- VC++ WIN32 sdk实现按钮自绘详解.
- Thinkphp 实现上一篇与下一篇的方法
- VC++ WIN32 sdk实现按钮自绘详解 之二(关键是BS_OWNERDRAW和WM_DRAWITEM)
- PHP函数utf8转gb2312编码
- ThinkPHP 系统常量列表
- Java中@Override的作用
- Struts中实现验证码生成和验证
- Java 设计模式 - 装饰模式
- java基础(7)--Java中的变量、数据类型、运算符
- Chromium网页绘图表面(Output Surface)创建过程分析
- 代码注入相关知识以及扫雷程序的分析(分析过程之后添加)
- C++之多态