windows上面捕获声卡数据

转自:http://shanewfx.github.io/blog/2013/08/14/caprure-audio-on-windows/

前一段时间接到一个任务,需要采集到声卡的输出信号,以便与麦克风的输入信号进行混音。

在考虑如何实现这个需求前,我们先讨论下电脑声音的三种模式:

1) render模式

该方式实际上就是播放(output)声音,常见的API如PlaySound, WaveOutXXX, DirectSound等

2) capture模式

该方式实际上就是录入(input)声音, 也就是我们通过麦克风输入声音,常见API如WaveInXXX

3)loopback模式

该方式就是我们需要实现的方式,即把扬声器里播放的声音抓取下来。

对于上面3种方式,render和capture方式应该比较好理解, 也都是系统有API直接支持的方式, loopback方式就比较奇怪了,在XP上该方式系统实际都没有正式支持, loopback的录制方式实际上也涉及到CD的版权问题。

之前一直没有研究过音频的相关技术,这次就顺便抽出一点时间去了解了一下Windows上采集音频的相关技术。

对于音频处理的技术,主要有如下几种:

采集麦克风输入

采集声卡输出

将音频数据送入声卡进行播放

对多路音频输入进行混音处理

1.Windows上音频处理的API

在Windows操作系统上,常用的音频处理技术主要包括:

Wave系列API函数、

DirectSound、

Core Audio。

其中,Core Audio只可以在Vista以上(包括Vista)的操作系统中才能使用,主要用来取代Wave系列API函数和DirectSound。

Core Audio实现的功能也比较强大,能实现对麦克风的采集、声卡输出的采集、控制声音的播放。

而Wave系列的API函数主要是用来实现对麦克风输入的采集(使用WaveIn系列API函数)和控制声音的播放(使用后WaveOut系列函数)。

DirectSound能够实现的功能估计和Wave系列API差不多,可能会更强一些(由于没有使用过DirectSound,不太肯定!)。

为了实现采集模块对操作系统的兼容性更好,基本上对麦克风输入的采集使用WaveIn系列API函数比较多;

在Windows XP系统中,没有直接提供对声卡输出进行采集的API,因此,在Windows XP要实现对声卡输出的采集会比较麻烦。
通常可选用支持混音的声卡,然后通过使用声卡的混音模块来实现采集,但并不是所有的声卡都支持混音的功能,这样的方案不具备通用性。

要实现通用性,可以采用虚拟声卡的方式来实现,从驱动层获取声卡的输出数据,但这种方案实现难度会比较大。

而在Vista以上的系统中,如Win7,则可以使用Core Audio中的API函数来实现采集声卡输出的功能。

对于混音模块的实现,目前基本是使用自定义的混音算法来完成功能,系统没有直接的API函数可供调用。

2.使用WaveIn系列API函数实现麦克风输入采集

涉及的API函数:

waveInOpen

开启音频采集设备,成功后会返回设备句柄,后续的API都需要使用该句柄

调用模块需要提供一个回调函数(waveInProc),以接收采集的音频数据

waveInClose

关闭音频采集模块

成功后,由waveInOpen返回的设备句柄将不再有效 ?

waveInPrepareHeader

准备音频采集数据缓存的空间

waveInUnprepareHeader

清空音频采集的数据缓存

waveInAddBuffer

将准备好的音频数据缓存提供给音频采集设备

在调用该API之前需要先调用waveInPrepareHeader

waveInStart

控制音频采集设备开始对音频数据的采集

waveInStop

控制音频采集设备停止对音频数据的采集

音频采集设备采集到音频数据后,会调用在waveInOpen中设置的回调函数。

其中参数包括一个消息类型,根据其消息类型就可以进行相应的操作。

如接收到WIM_DATA消息,则说明有新的音频数据被采集到,这样就可以根据需要来对这些音频数据进行处理。

(示例以后补上)

3.使用Core Audio实现对声卡输出的捕捉

涉及的接口有:

IMMDeviceEnumerator

IMMDevice

IAudioClient

IAudioCaptureClient

主要过程:

创建多媒体设备枚举器(IMMDeviceEnumerator)

通过多媒体设备枚举器获取声卡接口(IMMDevice)

通过声卡接口获取声卡客户端接口(IAudioClient)

通过声卡客户端接口(IAudioClient)可获取声卡输出的音频参数、初始化声卡、获取声卡输出缓冲区的大小、开启/停止对声卡输出的采集

通过声卡采集客户端接口(IAudioCaptureClient)可获取采集的声卡输出数据,并对内部缓冲区进行控制

(示例以后补上)

4.常用的混音算法

混音算法就是将多路音频输入信号根据某种规则进行运算(多路音频信号相加后做限幅处理),得到一路混合后的音频,并以此作为输出的过程。

我目前还做过这一块,搜索了一下基本有如下几种混音算法:

将多路音频输入信号直接相加取和作为输出

将多路音频输入信号直接相加取和后,再除以混音通道数,防止溢出

将多路音频输入信号直接相加取和后,做Clip操作(将数据限定在最大值和最小值之间),如有溢出就设最大值

将多路音频输入信号直接相加取和后,做饱和处理,接近最大值时进行扭曲

将多路音频输入信号直接相加取和后,做归一化处理,全部乘个系数,使幅值归一化

将多路音频输入信号直接相加取和后,使用衰减因子限制幅值

下面是XP时代的Audio架构图, 该架构下audio的合成和压缩都是在系统内核里进行的:

在XP这种方式下,我们要抓去声卡播放的声音没有正规的方式, 一般来说只有2中:

一种是虚拟声卡,还有一种就是Hook audio 播放相关的API (很多时候我们会发现API hook是没有办法时的全能办法 ^_^)

但是在Vista之后,微软修改了原来的媒体架构, 以COM的方式重新封装了core audio API:


以看到原来Auido的API (waveXXX, mixerXXX和DirectSound)都依赖下层的新封装的Core Audio
APIs,而且这些APi都工作在用户模式, 也就是说声音的合成是在用户模式下通过软件实现的。在Vista之后,
可以看到我们可以单独控制每个应用程序的声音了, 因为每路Audio都可以工作在不同的Audio session了。通过新的Core Audio
API, 我们可以很容易的实现声卡声音的抓取

时间: 2024-08-19 19:46:36

windows上面捕获声卡数据的相关文章

CentOS Rsync服务端与Windows cwRsync客户端实现数据同步

CentOS Rsync服务端与Windows cwRsync客户端实现数据同步 2012年05月06日 ? Rsync ? 暂无评论 ? 被围观 3,622次+ 说明: 1.Rsync服务端 系统:CentOS 5.5 IP地址:192.168.21.160 数据存放目录:/data/osyunwei 2.cwRsync客户端 系统:Windows Server 2003 IP地址:192.168.21.130 同步的目录:D:\osyunwei 实现目的: cwRsync客户端每天凌晨3:0

抓包工具 - Fiddler(如何捕获Android数据包)

如何捕获Android数据包 一.移动设备访问网络原理 先看看移动设备是怎么去访问网络,如图1所示,可以看到,移动端的数据包是从wifi出去的. 图1(移动设备访问网络) 所以我们可以把自己的电脑开启热点,将手机连上电脑,本机的Fiddler开启代理后,让这些数据通过Fiddler,那Fiddler就可以抓到这些包,然后发给路由器,如图2所示 图2(设置) 二.Fiddler抓取android数据包所需条件 1.电脑需要安装Fiddler 2.测试手机需要支持Wifi 3.测试手机与电脑需要同一

Windows 8.1 重复数据删除——规划部署(二)

一.规划部署目标   Windows 8.1&Server 2012 的重复数据删除设计为安装到主要数据卷上,而无需添加任何附加的专用硬件.这意味着你可以安装和使用该功能,而不会影响服务器上的主要工作负载.默认设置为非侵入性的,因为它们允许在处理特定文件之前数据"存留时间"达到五天,默认的最小文件大小为 32 KB.该实现是为低内存和 CPU 利用率而设计的.如果内存利用率变高,则重复数据删除功能将等待可用的资源.管理员可以根据所涉及数据的类型以及该卷或特定文件类型的更改频率和

Windows 8.1 重复数据删除——概念(一)

功能描述 重复数据删除指的是在数据中查找和删除重复内容,而不会影响其保真度或完整性.其目标是通过将文件分割成大小可以改变 (32-128 KB) 的小区块.确定重复的区块,然后为每个区块保留一个副本,从而在更小的空间中存储更多的数据.区块的冗余副本由对单个副本的引用所取代.区块会进行压缩,然后以特殊的容器文件形式组织到 System Volume Information 文件夹中. 针对卷启用了重复数据删除而且对数据进行优化之后,卷中会包含以下内容: 未优化的文件:例如,未优化的文件可以包括:无

Windows中使用MySQL 数据查询(三)

一.排序 select * from employees order by name; 字符型默认字符顺序(也就是说z永远比a大),不管大小写:如果想按编码值排序(也就是说小写永远大于大写),则使用 select * from employees order by binary name; 二.取前n条记录(n在本例中为3) select * from employees order by id limit 3; 三.日期时间函数 1.获取当前日期 select curdate(); 2.取年

捕获网络数据包并进行分析的开源库-WinPcap

什么是WinPcap WinPcap是一个基于Win32平台的,用于捕获网络数据包并进行分析的开源库. 大多数网络应用程序通过被广泛使用的操作系统元件来访问网络,比如sockets.  这是一种简单的实现方式,因为操作系统 已经妥善处理了底层具体实现细节(比如协议处理,封装数据包等等),并且提供了一个与读写文件类似的,令人熟悉的接口. 然而,有些时候,这种“简单的方式”并不能满足任务的需求,因为有些应用程序需要直接访问网 络中的数据包.也就是说,那些应用程序需要访问原始数据包,即没有被操作系统利

Windows Server 2012重复数据删除增强

容量优化. Windows Server 2012 中的重复数据删除可在更小的物理空间中存储更多数据.与使用单实例存储 (SIS) 或新技术文件系统 (NTFS) 压缩的之前版本相比,它实现了更高的存储效率.重复数据删除使用子文件可变大小分块和压缩,常规文件服务器的优化率为 2:1,而虚拟数据的优化率最高可达 20:1. 伸缩性和性能. Windows Server 2012 重复数据删除具有高度的可伸缩性,能够有效利用资源,并且不会产生干扰.它可以同时对多个大容量主数据运行,而不会影响服务器上

Wireshark数据抓包教程之认识捕获分析数据包

Wireshark数据抓包教程之认识捕获分析数据包 认识Wireshark捕获数据包 当我们对Wireshark主窗口各部分作用了解了,学会捕获数据了,接下来就该去认识这些捕获的数据包了.Wireshark将从网络中捕获到的二进制数据按照不同的协议包结构规范,显示在Packet Details面板中.为了帮助用户能够清楚的分析数据,本节将介绍识别数据包的方法. 在Wireshark中关于数据包的叫法有三个术语,分别是帧.包.段.下面通过分析一个数据包,来介绍这三个术语.在Wireshark中捕获

windows矢量字体点阵数据的提取(转)

源:windows矢量字体点阵数据的提取 1.提取原理 在windows系统当中提取矢量字体的字模有很多方法,下面介绍一种利用GetGlyphOutline来实现字模点数数据的提取. GetGlyphOutline是windows系统的API函数,利用这个函数,可以方便快捷提取矢量字体字符点阵数据,并且可以很好的支持从文本文件中读取字符.面对用大量字符数据输入时,获取点阵数据所需要的时间量也是很少. GetGlyphOutline函数声明如下: DWORD GetGlyphOutline( HD