windows麦克风输入采集

9 篇文章 0 订阅
3 篇文章 0 订阅

作者: 使徒保罗

邮箱:297329588szh@163.com

声明:您可以自由使用本文代码,如有任何疑问可通过群414742203交流

环境:win10 64位+qt5.7(mingw)

功能:qt调用The Windows Audio Session API (WASAPI), MMDeviceAPI采集声卡示例代码最低系统要求:客户端Windows Vista,服务器Windows Server 2008,手机Windows Phone 8

参考:https://msdn.microsoft.com/en-us/library/dd370800(v=vs.85).aspx


pro文件:

QT += core
QT -= gui
 
CONFIG += c++11
 
TARGET = WindowsCoreAduioDemo
CONFIG += console
CONFIG -= app_bundle
 
TEMPLATE = app
 
SOURCES += main.cpp
LIBS += -L$$PWD/lib/ -lOle32
 

main.cpp文件:

#include <QCoreApplication>
#include <Windows.h>
#include <MMDeviceAPI.h>
#include <AudioClient.h> //WSAPI
#include <AudioPolicy.h> //WSAPI
#define MAX_AUDIO_FRAME_SIZE 192000
 
#define SAFE_RELEASE(punk) \
            if((NULL != punk)) \
            { (punk)->Release(); (punk)=NULL; }
 
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
 
    IAudioClient *      _AudioClient = NULL;
    IAudioCaptureClient *_CaptureClient = NULL;
    IMMDevice * _Device = NULL;
    IMMDeviceEnumerator * _DeviceEnumerator = NULL;
    HANDLE _AudioSamplesReadyEvent = NULL;
 
    WAVEFORMATEX *      _MixFormat = NULL;
 
    BYTE *pBuffer = NULL;
 
    //初始化Com库
    HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if(hr != S_OK)
    {
        printf("初始化Com库失败\n");
        return -1;
    }
 
    //创建Com对象IMMDeviceEnumerator
    hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&_DeviceEnumerator));
    if (FAILED(hr))
    {
       printf("Unable to retrieve CoCreateInstance %x\n", (long)hr);
       return false;
    }
 
 
    //获取声音播放设备对象IMMDevice
    hr = _DeviceEnumerator->GetDefaultAudioEndpoint(eCapture,eMultimedia,&_Device);
    if (FAILED(hr))
    {
       printf("Unable to retrieve device %x\n", hr);
       return false;
    }
 
    //释放IMMDeviceEnumerator对象
    SAFE_RELEASE(_DeviceEnumerator)
    //在音频数据拷贝之前要添加一个引用,
    _Device->AddRef();
 
    //创建Com对象IAudioClient
   hr = _Device->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER, NULL, reinterpret_cast<void **>(&_AudioClient));
   if (FAILED(hr))
   {
       printf("Unable to activate audio client: %x.\n", hr);
       return false;
   }
 
   //获取音频引擎内如共享模式程序的音频流格式
   hr = _AudioClient->GetMixFormat(&_MixFormat);
   if (FAILED(hr))
   {
       printf("Unable to get mix format on audio client: %x.\n", hr);
       return false;
   }
 
   //wBitsPerSample是采样深度(位深)  nChannels是音频通道数 _FrameSize一个采样的大小(字节)
   size_t _FrameSize = (_MixFormat->wBitsPerSample / 8) * _MixFormat->nChannels;
 
   //初始化音频引擎
   /*
    *AUDCLNT_SHAREMODE_SHARED设置共享模式
    *AUDCLNT_STREAMFLAGS_EVENTCALLBACK允许设置事件通知回调 SetEventHandle才会有效果
    */
 
   hr = _AudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, 0, 0, _MixFormat, NULL);
   if (FAILED(hr))
   {
       printf("Unable to initialize audio client: %x.\n", hr);
       return false;
   }
 
   _AudioSamplesReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
   if (_AudioSamplesReadyEvent == NULL)
   {
       printf("Unable to create samples ready event: %d.\n", GetLastError());
       return false;
   }
 
   //设置事件通知对象
   hr = _AudioClient->SetEventHandle(_AudioSamplesReadyEvent);
   if (FAILED(hr))
   {
       printf("Unable to set ready event: %x.\n", hr);
       return false;
   }
 
   //生成采集服务
   hr = _AudioClient->GetService(IID_PPV_ARGS(&_CaptureClient));
   if (FAILED(hr))
   {
       printf("Unable to get new capture client: %x.\n", hr);
       return false;
   }
 
   //开始采集
   hr = _AudioClient->Start();
   if (FAILED(hr))
   {
       printf("Unable to get new capture client: %x.\n", hr);
       return false;
   }
 
 
   pBuffer=new BYTE[MAX_AUDIO_FRAME_SIZE];
   while (TRUE)
   {
       DWORD waitResult = WaitForSingleObject(_AudioSamplesReadyEvent, INFINITE);
 
       BYTE *pData = NULL;
 
       INT nBufferLenght = 0;
       UINT32 framesAvailable = 0;
       DWORD  flags = 0;
 
       hr = _CaptureClient->GetBuffer(&pData, &framesAvailable, &flags, NULL, NULL);
       if (SUCCEEDED(hr))
       {
           if (framesAvailable!=0)
           {
               if (flags & AUDCLNT_BUFFERFLAGS_SILENT)
               {
                   //告诉Copy Data写静音
                   pData = NULL;
               }
               else
               {                  
                   //Copy data from the audio engine buffer to the output buffer.
                   int nDataLen = framesAvailable*_FrameSize;
                   CopyMemory(pBuffer,pData,nDataLen);
                   printf("get capture audio len: %d!\n", nDataLen);
               }
           }          
       }
       _CaptureClient->ReleaseBuffer(framesAvailable);
 
   }
   delete[] pBuffer;
 
   SAFE_RELEASE(_DeviceEnumerator)
   SAFE_RELEASE(_Device)
 
   SAFE_RELEASE(_DeviceEnumerator)
   SAFE_RELEASE(_DeviceEnumerator)
   SAFE_RELEASE(_DeviceEnumerator)
   CoUninitialize();
   return a.exec();
}
 


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

使徒保罗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值