如何在云电脑串流中实现声音输入输出—虚拟声卡(虚拟扬声器和虚拟麦克风)开发


虚拟声卡(虚拟扬声器和虚拟麦克风)技术原理简介

1. 背景

近些年云计算的发展可谓是势不可挡,无论是办公还是娱乐等行业都开始使用云计算来逐步替代直接使用本地物理硬件的技术,例如:

  1. 服务器部署。相比之前,现在部署一个服务器都非常简单;我们只需要在阿里云,华为云等购买相关主机(虚拟机)和服务即可,根本无需在公网部署一个硬件设备,这样我们非常容易就拥有了自己个人的公网服务器。
  2. VDI云桌面。该项技术目前主要是针对内网办公场景,企业通过桌面云集中管理员工虚拟主机,达到数据安全,集中管理,快速重复利用,一键式部署等功能。
  3. 云游戏。随着4G和5G网络的飞速发展,游戏也开始逐渐云化,很多传统游戏厂商和VR游戏厂商都开始支持云游戏;借助云游戏,我们如果需要玩大型游戏,本地无需高性能GPU和CPU的支持,甚至本地无需要对游戏进行直接安装,我们使用简单(廉价)终端就可以通过云游戏技术来体验大型游戏,达到与本地一致的体验效果。

我们以VDI云桌面办公为例,其大致的部署架构如下:

在这里插入图片描述

如上图,一般来说:

  1. 客户端:指的是我们的瘦终端,一般使用的是普通硬件,比如性能比较差但是价格比较廉价的个人终端电脑。
  2. 服务器:这里指的是我们的虚拟机,是我们真实运行的主机(安装了各种办公应用或者游戏的虚拟机),它一般有高性能,方便管理等特性。

在云计算的背景下面,虽然我们云主机(上图的虚拟机)运行在了远端,给使用和管理带来了非常大的便捷,但是也带来了很大技术上面的困难。例如声音的播放和录制相比本地的使用实现就复杂很多,下面举几个相关例子:

  1. 如果我们使用云游戏,一个非常通用的功能就是接麦;由于我们的云主机一般是虚拟机,没有接入麦克风,这个时候如果需要接麦的话就会非常麻烦(如果是物理主机,麦克风在本地,远端主机也无法连接本地麦克风)。
  2. 如果我们使用VDI云桌面,也有类似的场景,例如我们使用直播软件或者教学软件进行声音广播;或者我们使用电话软件进行拨号的时候也是需要麦克风支持的,此时麦克风硬件在也是无法达到要求。
  3. 对于扬声器来说,虽然我们可以直接对扬声器声音进行捕获,然后在客户端(瘦终端)进行播放,但是虚拟机并没有扬声器设备,因此也无法达到需求(用户程序无法进行音频播放)。

面临这些问题,我们需要在虚拟机有扬声器和麦克风,并且需要能够做到:

  1. 扬声器:最基础的功能需要让用户软件可以识别到扬声器设备,并使用该扬声器进行声音播放,当然我们也可以在驱动中获取应用程序播放音频数据。
  2. 麦克风:麦克风就比较麻烦了,麦克风仅仅让相关用户软件能够识别到硬件设备还不足已解决问题,对于麦克风设备还需要支持喂数据的操作,将需要录制的音频直接传递给麦克风,达到真实声音录制的效果。

要解决上面这些问题,就需要在虚拟机中对声卡进行虚拟化,实现虚拟声卡驱动程序,使得用户程序能够使用扬声器播放声音以及可以对麦克风喂数据,将本地麦克风的数据喂给虚拟机的虚拟麦克风。

下面,将通过本文来分析虚拟声卡的实现原理,来实现虚拟扬声器和虚拟麦克风的功能。

2. 技术概要

2.1 用户层声音架构

在XP下面,Windows对于声音的处理架构基本如下:
在这里插入图片描述

这种架构只有在XP系统下才支持,在这种模式下面我们可以发现,如果对于扬声器声音采集的话会非常麻烦,要么使用HOOK,要么实现虚拟扬声器在驱动中拷贝数据。

因此Windows在Vista版本对音频的架构做了很多的调整,Vista之后的版本架构如下:
在这里插入图片描述

该架构下面,所有的声音都通过Core Audio API来进行控制,该架构下面声音有三种模式进行处理:

  • render模式 :该方式实际上就是播放声音,常见的API如PlaySound, WaveOutXXX, DirectSound,IAudioRenderClient等,具体的如何使用扬声器进行音频播放不是本文的重点,如果想了解Windows上的音频播放可以参考如下MSDN链接

https://learn.microsoft.com/en-us/windows/win32/coreaudio/rendering-a-stream

  • capture模式 :该方式实际上就是录入声音, 也就是我们通过麦克风输入声音,常见API如WaveInXXX,IAudioCaptureClient, 如果想了解更多关于如何从麦克风采集数据请参考如下MSDN链接:

https://learn.microsoft.com/en-us/windows/win32/coreaudio/capturing-a-stream

  • loopback模式 : 该方式就是把扬声器里播放的声音抓取下来,通常我们看到的流推软件中声音的推送就是使用该模式采集的。

在Vista系统音频架构中,我们对音频的开发也相对简单:

  1. MMDevice API:表示声音设备相关的接口,例如枚举声音设备等等。
  2. WASAPI:这个是Windows 声音会话相关的所有API,我们看到的IAudioClient等接口,以及最关键用于播放扬声器的IAudioRenderClient接口以及采集麦克风的音频数据的IAudioCaptureClient,都是由他提供。
  3. DeviceTopologyAPI:这个是设备拓扑结构管理的API,用于遍历音频设备适和音频终端的内部拓扑,并可以决定音频设备的连接顺序,通过DeviceTopology API中的接口和方法, 我们可以沿着Audio Adapter的硬件设备里的数据通道数据流程进行之配置,比如对音频终端设备的数据路径上流经音频数据流进行音量控制。
  4. EndPointVolumeAPI:这个是音量控制相关的API。

上述图中,声音的播放分为共享模式和独占模式:

  1. 共享模式:每个用户程序都在自己的会话进行声音播放,然后提交给声音播放引擎进行合成然后提交给底层驱动。
  2. 独占模式:用户程序直接将数据提交给驱动,音频数据不在经过声音播放引擎,因此一旦开启独占模式,那么其他共享模式的声音就无法播放了。

2.2 过滤器(Filter)

在Windows下面音频数据是通过内核流(Kernel Stream)的形式进行处理的,一份音频数据要从本地文件中到扬声器进行播放,需要经过多方面的处理,每一次的处理可以抽象一个一个过滤器处理过程,如下:
在这里插入图片描述

如上图,我们音频数据的处理过程如下:

  1. 通过引脚流入过滤器。
  2. 过滤器经过节点0对数据进行处理。
  3. 节点0对数据完成处理之后,通过引脚交给节点1.
  4. 节点1完成数据的之后之后,该过滤器完成对该数据的处理,流出过滤器。
  5. 流出该过滤器之后,将数据交给下一个连接的过滤器。

从这里我们引入四个概念引脚,节点,连接,和过滤器,对应音频流数据处理的各个点。

2.3 拓扑结构

拓扑结构这个概念是比较复杂的,而且在用户态设备的拓扑结构和驱动的概念也不一样;由于本文我们分享的是虚拟声卡的技术,我们这里说的是驱动的拓扑结构。对于一个音频设配器来说,一个典型的拓扑结构图如下:

  • 27
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值