windows编程之音频设备的捕获

#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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Windows操作系统下,我们可以使用C/C++编程语言来捕获资源管理器文件的修改。首先,我们需要使用Windows API来访问资源管理器的相关功能。 首先,我们可以使用FindFirstChangeNotification函数来监视指定路径下的文件和子文件的修改。该函数需要传入要监视的路径和一个布尔值来指示是否监视子文件夹的修改。一旦文件或文件夹的修改被监测到,该函数将返回一个句柄。 接下来,我们可以使用WaitForSingleObject函数等待资源管理器文件的修改通知。该函数需要传入之前获得的句柄和超时时间,以等待通知的到来。如果文件或文件夹的修改被监测到,该函数将返回WAIT_OBJECT_0的值。 一旦我们获得了资源管理器文件的修改通知,我们可以通过遍历文件夹中的文件来确定哪些文件被修改了。可以使用FindFirstFile和FindNextFile函数来获取文件夹中的文件信息,并通过比较文件的修改时间等属性来判断是否被修改。 最后,我们可以进行一些处理操作,比如打印被修改的文件名、复制被修改的文件等。 需要注意的是,捕获资源管理器文件的修改是基于轮询机制的,即需要我们使用循环来不断检查是否有文件被修改。在需要停止监测时,我们可以使用FindCloseChangeNotification函数来关闭资源管理器文件的修改监测。 总之,通过使用C/C++编程语言和Windows API,我们可以实现对资源管理器文件的修改捕获功能,以便实时监测文件的修改情况并进行相应的处理操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值