音频采集-windows采集-----04-----obs源码wasapi模块分析

本文分析了OBS在Windows下使用WASAPI进行音频采集的方式,重点介绍了WASAPISource类,包括其控制采集输入源、构造函数、Start()函数以及CaptureThread()线程的工作原理。详细讲解了音频设备的初始化、线程采集的流程和音频数据的处理过程。
摘要由CSDN通过智能技术生成

上一个wasapi demo已经很详细的说明如何采集音频了,也完全可以应用在商业的代码中。
但是人嘛,总是想使用更好的代码,我也不例外,我们知道obs在windows下采集音频就是使用wasapi,所以我们去看看obs是如何使用的。

obs是通过插件就行加载的,使得我们比较容易找到它的wasapi模块,路径:obs-studio\plugins\win-wasapi
主要的逻辑实现放在了win-wasapi.cpp中。

在这里插入图片描述

obs音频采集插件在程序启动的时候就创建好了,包括扬声器声音捕获 wasapi_output_capture 和麦克风声音捕获 wasapi_input_capture 。两者管理都是通过 class WASAPISource 对象来管理。

也就是说,obs实现wasapi的关键代码,看class WASAPISource 类即可。

一 obs的class WASAPISource 介绍

1. 控制采集输入源

WASAPISource类支持采集扬声器和麦克风。通过以下枚举进行控制:

enum class SourceType {
   
	Input,
	DeviceOutput,
	ProcessOutput,
};

其中:
● Input:代表采集麦克风。
● DeviceOutput:采集电脑的扬声器。
● ProcessOutput:暂未研究。可以先忽略。

在下面分析obs的WASAPISource类时,我们以采集扬声器即SourceType=DeviceOutput,并且以线程采集为例进行讲解。

2. WASAPISource的构造函数

WASAPISource的构造函数会进行对应的初始化,所以如果我们想知道obs如何初始化wasapi插件的话,可以在WASAPISource的构造函数加个断点。
在这里插入图片描述

下面我们开始对WASAPISource的构造函数逻辑进行说明。

  1. 通过windows的CreateEvent函数,创建相关事件,用于初始化、接收数据、重连、停止、退出等等。
  2. CoCreateInstance()枚举音频设备。
  3. 判断windows系统是否支持rtwq队列处理。若支持,rtwq_supported=true,则会使用rtwq的相关接口进行音频采集;若不支持,会开启一个线程进行音频采集,线程处理函数是WASAPISource::CaptureThread()。对于rtwq队列采集和线程采集,前者微软进行优化过,效果更好,但是需要更高的windows版本才能支持,而线程则兼容性更好。这里我们就只分析线程采集就行,因为这样会更兼容不同版本的windows。
  4. 开启Start()。
WASAPISource::WASAPISource(obs_data_t *settings, obs_source_t *source_,
			   SourceType type)
	: source(source_),
	  sourceType(type),
	  startCapture(this),
	  sampleReady(this),
	  restart(this)
{
   

  // 加载相关动态库接口
	mmdevapi_module = LoadLibrary(L"Mmdevapi");
	if (mmdevapi_module) {
   
		activate_audio_interface_async =
			(PFN_ActivateAudioInterfaceAsync)GetProcAddress(
				mmdevapi_module, "ActivateAudioInterfaceAsync");
	}

  /* 参数设置相关, 可以替换为自己的参数 */
	UpdateSettings(BuildUpdateParams(settings));
	LogSettings();

  // 创建相关事件,用于初始化、接收数据、重连、停止、退出等等。
	idleSignal = CreateEvent(nullptr, true, false, nullptr);
	if (!idleSignal.Valid())
		throw "Could not create idle signal";

  // 省略相关事件的创建...

	notify = new WASAPINotify(this);
	if (!notify)
		throw "Could not create WASAPINotify";

  // 枚举音频设备
	HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr,
				      CLSCTX_ALL,
				      IID_PPV_ARGS(enumerator.Assign()));
	if (FAILED(hr))
		throw HRError("Failed to create enumerator", hr);

	hr = enumerator->RegisterEndpointNotificationCallback(notify);
	if (FAILED(hr))
		throw HRError("Failed to register endpoint callback", hr);

	/* OBS will already load DLL on startup if it exists */
	const HMODULE rtwq_module = GetModuleHandle(L"RTWorkQ.dll");

	// while RTWQ was introduced in Win 8.1, it silently fails
	// to capture Desktop Audio for some reason. Disable for now.
	struct win_version_info win1703 = {
   }
  • 18
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值