当前位置: 首页 > news >正文

windows 桌面采集音频

头文件:

#ifndef __CAPTURE_AUDIO__
#define __CAPTURE_AUDIO__#include <functional>
#include <windows.h>
#pragma comment(lib, "winmm.lib")class CaptureAudio
{
public:CaptureAudio();~CaptureAudio();public:bool Init(const std::function<void(unsigned char* pPcmAudioData, long nLen)>& pFunc);void Uninit();private:bool Capture();private:static unsigned int __stdcall Process(void* args);private:unsigned char* m_pAudioData = nullptr;private:HANDLE m_threadRecv = INVALID_HANDLE_VALUE;HANDLE m_threadEvent = INVALID_HANDLE_VALUE;private:WAVEHDR m_wHdr; //采集音频时包含数据缓存的结构体HWAVEIN m_hWaveIn;//输入设备private:std::function<void(unsigned char* pPcmAudioData, long nLen)> m_pFunc;
};#endif

源文件:

#include "CaptureAudio.h"
#include <chrono>
#include <thread>using namespace std;CaptureAudio::CaptureAudio()
{while (!m_pAudioData) {try{m_pAudioData = new unsigned char[1024 * 1024];}catch (...){}}
}
CaptureAudio::~CaptureAudio()
{if (m_pAudioData) {delete[]m_pAudioData;m_pAudioData = nullptr;}
}bool CaptureAudio::Init(const std::function<void(unsigned char* pPcmAudioData, long nLen)>& pFunc)
{UINT nDev = waveInGetNumDevs();if (nDev == 0) {return false;}WAVEFORMATEX waveform; //采集音频的格式,结构体waveform.wFormatTag = WAVE_FORMAT_PCM;//声音格式为PCMwaveform.nSamplesPerSec = 48000;//采样率,16000次/秒waveform.wBitsPerSample = 16;//采样比特,16bits/次waveform.nChannels = 1;//采样声道数,2声道waveform.nAvgBytesPerSec = 16000;//每秒的数据率,就是每秒能采集多少字节的数据waveform.nBlockAlign = 2;//一个块的大小,采样bit的字节数乘以声道数waveform.cbSize = 0;//一般为0MMRESULT hResults = waveInOpen(&m_hWaveIn, WAVE_MAPPER, &waveform, (DWORD_PTR)0, (DWORD_PTR)this, CALLBACK_NULL);//使用waveInOpen函数开启音频采集if (hResults != MMSYSERR_NOERROR) {return false;}m_threadEvent = CreateEvent(NULL, true, false, L"");m_threadRecv = (HANDLE)_beginthreadex(NULL, 0, Process, this, 0, NULL);m_pFunc = pFunc;return true;
}void CaptureAudio::Uninit()
{if (m_threadRecv != INVALID_HANDLE_VALUE && m_threadEvent != INVALID_HANDLE_VALUE) {SetEvent(m_threadEvent);WaitForSingleObject(m_threadRecv, INFINITE);CloseHandle(m_threadRecv);CloseHandle(m_threadEvent);m_threadRecv = INVALID_HANDLE_VALUE;m_threadEvent = INVALID_HANDLE_VALUE;}waveInUnprepareHeader(m_hWaveIn, &m_wHdr, sizeof(WAVEHDR));waveInStop(m_hWaveIn);waveInClose(m_hWaveIn);
}bool CaptureAudio::Capture()
{waveInUnprepareHeader(m_hWaveIn, &m_wHdr, sizeof(WAVEHDR));memset(m_pAudioData, 0, 1024 * 1024);m_wHdr.lpData = (LPSTR)m_pAudioData;m_wHdr.dwBufferLength = 1024 * 1024;m_wHdr.dwBytesRecorded = 0;m_wHdr.dwUser = 0;m_wHdr.dwFlags = WHDR_DONE;m_wHdr.dwLoops = 1;waveInPrepareHeader(m_hWaveIn, &m_wHdr, sizeof(WAVEHDR));//准备一个波形数据块头用于录音waveInAddBuffer(m_hWaveIn, &m_wHdr, sizeof(WAVEHDR));//指定波形数据块为录音输入缓存MMRESULT hResults = waveInStart(m_hWaveIn);//开始录音if (hResults != MMSYSERR_NOERROR) {return false;}std::this_thread::sleep_for(std::chrono::milliseconds(100));waveInReset(m_hWaveIn);if (m_pFunc) {m_pFunc(m_pAudioData, m_wHdr.dwBytesRecorded);}return true;
}unsigned int CaptureAudio::Process(void* args)
{CaptureAudio* pThis = (CaptureAudio*)args;while (true) {if (WaitForSingleObject(pThis->m_threadEvent, 0) == WAIT_OBJECT_0) {break;}pThis->Capture();}return 0;
}

生成的文件pcm:

 

相关文章:

  • 为什么 Kubernetes 的设计中有 Pod,而不是直接使用容器
  • sysbench 命令:跨平台的基准测试工具
  • 算法训练营打卡Day19
  • 66 使用注意力机制的seq2seq_by《李沐:动手学深度学习v2》pytorch版
  • python如何判断图片路径是否存在
  • Ubuntu网卡配置
  • 微信小程序 图片的上传
  • KKT实际运用 -MATLAB
  • 通信工程学习:什么是DQDB分布式队列双总线
  • 北京数字孪生工业互联网可视化技术,赋能新型工业化智能制造工厂
  • 基于微信小程序的健康管理系统(源码+定制+文档)
  • 【设计模式-策略】
  • 网络编程,tcp,守护进程化,前后台任务,bash与shell,会话
  • CSS中的字体样式、文本样式、列表样式以及背景和渐变
  • 基于基于微信小程序的社区订餐系统
  • @angular/forms 源码解析之双向绑定
  • Android交互
  • HTML-表单
  • HTTP请求重发
  • Mac转Windows的拯救指南
  • Nacos系列:Nacos的Java SDK使用
  • Python学习笔记 字符串拼接
  • Redash本地开发环境搭建
  • text-decoration与color属性
  • 构建工具 - 收藏集 - 掘金
  • 基于Mobx的多页面小程序的全局共享状态管理实践
  • 如何正确配置 Ubuntu 14.04 服务器?
  • 王永庆:技术创新改变教育未来
  • 蚂蚁金服CTO程立:真正的技术革命才刚刚开始
  • 如何在招聘中考核.NET架构师
  • ​​快速排序(四)——挖坑法,前后指针法与非递归
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • # linux从入门到精通(三)
  • #ifdef 的技巧用法
  • #数据结构 笔记三
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (十三)Flink SQL
  • (原創) 如何解决make kernel时『clock skew detected』的warning? (OS) (Linux)
  • (转)h264中avc和flv数据的解析
  • (转)http-server应用
  • (转)项目管理杂谈-我所期望的新人
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • ***汇编语言 实验16 编写包含多个功能子程序的中断例程
  • .NET 4.0中的泛型协变和反变
  • .Net Core 笔试1
  • .NET LINQ 通常分 Syntax Query 和Syntax Method
  • .NET 线程 Thread 进程 Process、线程池 pool、Invoke、begininvoke、异步回调
  • .net6Api后台+uniapp导出Excel
  • .netcore如何运行环境安装到Linux服务器
  • @Tag和@Operation标签失效问题。SpringDoc 2.2.0(OpenApi 3)和Spring Boot 3.1.1集成
  • [ C++ ] template 模板进阶 (特化,分离编译)