代码改变世界

DirectShow音频采集

2007-08-16 18:06  libiver  阅读(599)  评论(0编辑  收藏  举报

        学习了好长一段时间的directshow,关于视频那一块的一些部分简单地过了一遍,如采集、解压缩、传输 等。现在回过头来学习音频的采集。现在将这几天的学习心得写下来。

 

我们知道directshow对我们的硬件的支持是通过特定的包装Filter来实现的,如我们的声卡是使用的Audio Captue Filter,他在内部有使用了以waveIn开头的一些API函数来实现(学过windows编程就知道,如waveInOpen).这些我们可以通过GraphEdit来检查。

 

下面我们在建一个完整的Filter Graph链路。如下:

 

                                     图(1

注意:这里用到了一个FilterWAV Dest。他是我们的DirectShow SDK中的一个例子,位于SDK安装目录的DirectShow/Samples/C++/DirectShow/Filters/WavDest下,主要的功能是在采集时,即PCM数据前部写入文件之后,再在文件头位置插入一个Wave格式的数据块。我们如果要使用到这里,我们必须首先需要编译这个例子并且注册成功后,才能从GraphEdit中添加到这里使用。

由于我们在写入文件的同时,我们需要实时监听,故我们可以使用Smart Tee,当然我们也可以使用Microsoft为我们在DirectShow SDK中提供的Infinite Pin Tee,位于SDK安装目录的DirectShow/Samples/C++/DirectShow/Filters/InfTee下,作用是将输入Pin上输入的数据复制多份(可以多于2),然后通过输出Pin发送出去。他的使用同WAV Dest

 

                                      图(2

    好了,现在开始编写我们的代码了,当然首先要创建一个Audio Capture Filter,由于不同的机器有不同的声卡,还有的机子可能不止一块声卡,所以我们要像采集视频是创建Video Capture Filter一样去枚举系统设备,找到了后再创建。在这里这个过程不在重复了。

并且Microsoft为我们提供了一个好的例子,位于SDK安装目录的DirectShow/Sample/C++

/DirectShow/Capture下的AudioCap。我们可以来参考它。

我们在GraphEdit中加入我们的声卡后会发现它只有一个Capture Output Pin,却有好几个Input Pin。需要说明的是,在GraphEdit中,这些Input Pin 并没有真正的数据流入,他们只是声卡的各个输入端子的象征性表示,所以这些Input Pin永远也不用连接。但是我们在选择了输入端子后,我们必须保证我们的物理连接正确。

AudioCap例子中使用了一个列表控件,同时他还给我们提供了很多很好的工具函数(mfcutil.cpp文件中, 当建立基于对话框的MFC应用程序时,它可以给我们带来方便),在这里我不赘述,大家可以自己看。

 

我们建立一个基于对话框的MFC应用程序AudioCap。下面是步骤:

①枚举并显示系统设备

 

枚举并显示声卡的给个输入pin

 

构建Filter Graph

 

 

现在创建声卡并加到Filter Graph

 

按图(1)或图(2)建立整个Filter Graph,在这里我就不写代码了,可以自己添加。

设置输入端子。这是采集音频与采集视频不同的地方,也是最重要的必不可少的一步。

在声卡Filter的给个输入Pin上我们都可以得到IAMAudioInputMixer接口,通过这个接口我们可以设置各个输入端子的音频属性,包括进行音频的合成时是否允许某个输入端子的音频参与混合、音频输入的音量、高音、低音等参数,当然这个接口还可以设置那个输入Pin为我们的输入端子。

运行程序

   当然如果我们的Filter Graph构建成功并且各个Filter连接也成功,就可以运行了

   

    好了,这就是我们采集音频的整个过程,实际上他是很简单的,但也有一些问题需要我们注意。如:我们在选择了输入端子后,要保证它的物理连接。比如我们选择了麦克风作为输入端子,就要保证机子上的麦克风连接正确而且是可用的

注①:我在利用CListBox控件时,要注意它在显示时是对字符串自动排序显示的,所以我们要在它的属性Sort里去掉这个属性,设置Sortfalse。不然我们在选择输入pin时会出错,因为CListBox控件里显示的可能与我们同枚举得到的序号并不一致。