windows音频声卡采集
来源:互联网 发布:淘宝seo从入门到精通 编辑:程序博客网 时间:2024/09/21 09:01
作者: 使徒保罗
邮箱:297329588szh@163.com
声明:欢迎交流学习,如有任何疑问,请通过邮箱联系本人
环境: win10 64位+qt5.7(MINGW)
参考:[微软还回录音文档](https://msdn.microsoft.com/en-us/library/dd316551%28v=vs.85%29.aspx)
功能: qt调用The Windows Audio Session API (WASAPI) 采集声卡示例代码
最低系统要求: 客户端Windows Vista,服务器Windows Server 2008,手机Windows Phone 8
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(eRender,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只用共享模式才能在还回(loopback)模式下起作用
*AUDCLNT_STREAMFLAGS_EVENTCALLBACK允许设置事件通知回调 SetEventHandle才会有效果
*AUDCLNT_STREAMFLAGS_LOOPBACK设置音频为还回模式,
*这样WSAAPI客户端就能捕获渲染断点设备播放的音频流
*/
hr = _AudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_LOOPBACK|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 0
- windows音频声卡采集
- windows 下wav采集音频
- 声卡采集
- windows phone 7音频采集方案
- Windows上的音频采集技术(转)
- windows音频PCM采集及简单编码
- Windows上的音频采集技术
- webrtc windows api音频采集总结
- Windows上的音频采集技术(转)
- Windows上的音频采集技术
- windows下简单的音频采集示例
- Windows下wave API 音频采集
- Windows上的音频采集技术
- Windows 下音频数据采集和播放
- 【VS开发】Windows上的音频采集技术
- FFMPEG在Windows上采集视频和音频
- MATLAB 声卡连续信号采集
- Android 音频采集---原始音频
- 文章标题
- Remote connection by VNC in CentOS 7
- RTF文件格式研究报告
- theano学习--conv2d
- Java基础-修饰符
- windows音频声卡采集
- java正则表达式的matcher
- 垃圾回收(三)-gc模块
- clnt_call(3)
- 网易AI英雄风云榜评选:谁是2017 年AI人物 TOP 10? | 评选
- 谷歌推出AVA数据库:让机器识别视频中人类行为 | 研究
- SSM综合项目实战(TTSC) -- day08 单点登录,注册登录,jsonp
- 五分钟搞懂并查集
- AI作家陆续上岗!是谁说的创作工作不会被替代? | 讨论