最近要做一个软件,需要实时录音,matlab似乎可以实现,但是好像也很麻烦。毕竟最后还是要在VS平台上做,所以就先开始试试实时录音吧。
比之前播放用的Media Control Interface (MCI)要麻烦的多的时,实时录音需要和声卡进行通信,因此对硬件有一定的要求。博主会认真给大家一点点分析,最终提供简单易懂的代码啦。
MMAPI可以把音频流缓冲起来并一块一块地发送给你,我把这里的音频的最小单位称为普朗克音频(从普朗克时间和普朗克长度那里获得灵感啦)。它有固定的大小,需要一次性处理完毕,当然也可以开一个多线程来处理保证稳定。数据有多少字节可以根据实际情况来设定。在性能和延迟之间均衡考虑一下,200ms的数据可以应付大多数情况。
当然。。。其实我需要的是至少100ms的数据,暂且先这样吧。。。
MMAPI的操作十分定式:
首先理解MMAPI的回调函数:
MMAPI的回调函数:
这个回调函数是来处理消息的,一开始收到WIM_OPEN,最后收到WIM_CLOSE唯一频繁收到的消息是WIM_DATA,得到这个消息时我们需要转移缓冲区里的数据并把缓冲区压入到设备缓冲队列中,你可以理解为自动pop手动push。
开始录音的流程为:以一种格式打开波形输入设备,发送WIM_OPEN消息给回调函数,准备缓冲区,添加缓冲区到设备,告诉设备录音开始;
具体操作:
录音期间循环发送WIM_DATA给回调函数;
结束录音的流程为:告诉设备录音结束并发送WIM_DATA给回调函数让它处理最后的数据,重置录音设备,释放缓冲区,至此可以重新设置缓冲区到设备并开始新的录音,关闭设备并发送WIM_CLOSE给回调函数。
这里用到双缓冲乃至多缓冲技术:
假设一个实时接水的任务,听起来奇怪但与MMAPI的处理流程相似,这里需要你用杯子连续接水,杯子相当于你开辟的缓冲区:
根据上面的流程,你的身份是MMAPI的回调函数,在饮水机面前要拿着杯子执行这个任务:任务的基本指标是滴水不漏地连续用杯子把水接到一个存储区域里,你要接指定量的水,还要负责转移走这杯水。为了能腾出时间把水倒在存储区域里,你肯定需要用不止一个杯子轮流接水。饮水机有一个功能:每当杯子灌满后,饮水机会通知你,并自动去接下一个杯子,如果后面没有杯子则终止任务。(不会讲故事的我啊TT,这个奇葩例子能看懂就行)可以见得:1.你会被及时地通知去转移数据2.缓冲区用完了要及时放回缓冲区队列后端以保证任务能够继续3.如果转移并处理数据的时间不是很稳定,你可能需要准备多个缓冲区而不是单纯增加缓冲区容量,为的是确保任务中能够预留足够多的容忍时间供你使用。
这里的多缓冲技术浅显地解释就是多个缓冲区排成一个队列(或者理解为放成一摞)来抵消这个任务中那些耗时不稳定的处理过程对整个实时处理任务的连续性带来的负面影响。其实生活中有很多事情也是用到多缓冲这个概念。
这是原作者讲的哈,但是要是没看懂的话,我给大家讲一下我的理解:
我们用MCI函数库能做到的是直接去录音然后去放音。但是现在因为我需要每一段普朗克音频的音量、频率等信息,因此直接录音整段肯定是不符合要求的。所以我们需要把一整段给拆成好多个一小段。那录这每一小段(即普朗克音频)的时候,我不能说录完这么多音频了,就给你处理,然后清空缓存区,再去录音。这样肯定会损失一定的音频信息。所以我们可以拿两个缓冲区。一个缓冲区录音,一个缓冲区处理,交替以往直到彻底完成任务。