说明:本问最早于2009年发于驱动开发网,现原文拷贝过来,将其收入我的博文中,供大家参考
最近很多朋友在讨论虚拟声卡驱动的问题,
借此机会我简单说下虚拟声卡及其应用.
参考代码:
DDK中msvad.
推荐参考软件:
VAC(VirtaulAudoo Cable),大家可以在下面“http://software.muzychenko.net/eng/vac.html ”下到Demo版的可执行文件。
该软件是俄国人写的,说实话,该软件的代码可读性很差,甚至是相当糟糕(或许作者有意将代码写成这样的),同时也很佩服作者能把那样难读的代码写到如此功能。
应用:
通常情况下,虚拟声卡驱动主要应用到截取声音,理论上可以做到截取几乎所有软件的声音,包括(但不限于)Windows自身的声音(如:警告提示等);MediaPlayer、PowerDVD、录音机和MP3播放器等流行软件,注意:这里所说的是几乎所有的声音,具体原因将在下面说明。
下面将以VAC的应用简单说明下如何实现音频截取功能(时间关系,这里仅说明Playback的截取)。
首先,VAC是一个虚拟声卡驱动,所谓虚拟声卡有两个含义,其一他是一个声卡驱动,其而,该声卡驱动没有对应相应硬件(说到这里我想指出一个很多人的错误概念,经常听人把DDK中的kbdfilter等驱动说成是虚拟键盘驱动,其实这个概念是不正确的,kbdfilter实际是一个键盘filter驱动,而并无“虚拟”的概念。)。
了解了VAC的具体含义后,我们再来看VAC如何实现声音截取功能的,我们还得先成音频播放和录音说起。
通常我们在进行录音和回放的时候,应用程序中我们可以选择wave API或者DirectSound等来实现,无论应用使用什么接口去实现,最终的数据流都将经过驱动到达声卡从而达到发音的目的,所以这里就仅以wave API来做说明。
通常我们播放声音是通过waveOutOpen打开声音设备,然后调用waveOutPrepareHeader、waveOutWrite将数据写声卡,当播放结束后,我们将收到MM_WOM_DONE消息或者事件被触发(具体是消息还是事件是根据waveOutOpen的fdwOpen和dwCallback决定的,这里就不多说了),然后我们可以waveOutUnprepareHeader来回收使用的资源,并将新的数据写入,这样声音就可以播放出来了,同样的道理我们可以实现录音(当然使用的API有所不同)。
大家都知道,当我们在调用waveOutOpen打开声卡的时候,有给一个uDeviceID,这个ID是用来标识别音频设备的,从0到N(最大设备ID),通常的软件都是使用缺省的音频设备,当安装了VAC后,系统中将有另外一个声卡,也就是说这里的deviceid将增加一个,正常情况下,即使我们安装了VAC,系统缺省的音频设备仍然是原始声卡,所以这个时候播放器并不能将声音发送到VAC,而是原始声卡,为了让声音能发送到VAC,我们需要改变这个数据流向,方法就是:我们将系统缺省设备设置为VAC,这样数据被发送到了VAC中,因为VAC并不对应声卡,所以我们将听不到声音了,当然这个并不是我们所需要,为了不影响使用,我们将必须将数据回写到真实声卡,在VAC中,它是通过waveIn来采集到其它软件写入的声音,然后通过waveOut来回写声卡实现的(具体实现代码很简单,我就不在这里show了)。
说到这里,我想大家已经很清楚前面说到通过VAC我们可以抓到“几乎所有的声音”的原因了,如还不明白的请大家仔细思考下应该可以想到原因。
上面简单说明了下虚拟声卡的应用和应用原理,详细细节还需要大家仔细琢磨和实践。
有兴趣的朋友可以去下一个VAC来玩玩,也可以去修改msvad实现你自己的VAC功能。