当前位置:0101部落 >> 技术文档 >> Windows >> 浏览文章 【字体:
Win32下的编程实现录音
作者:未知 日期:2007年08月21日 阅读次数: 来源:互联网
 
1      引言
在Win32 APIs基础上编写录音程序繁琐易错,使用封装好的类是个不错的注意。不幸的是所谓封装好的类对你而言,往往是代码罗嗦且功能不足,因此尽管你可能希望在某个项目上因使用封装好的类而避开Win32 APIs,可最终你发现你还得面对它。不是为了编写自己的类,就是为了修改别人的代码。
Win32 APIs中有一组被称成多媒体控制接口(即MCI)的函数,该接口提供了多媒体编程所需的系统级APIs。对绝大多数C/C++程序员而言,这些函数也就是Windows多媒体编程的最低层接口。
由于录音代码直接操作真实的录音设备而非单纯的逻辑过程,因此会遇到一些“意外”或与时序有关的困难,从而使编写健壮的代码成了一件困难的事。
录音的目的往往是将声音写入文件保存下来或是通过网络发送,这两类需求对录音代码影响较大。前者无实时性要求,一般也不限制数据量,代码较易编写,而后者既对实时性又要求,又对数据量(也就是音频格式)有要求,且网络系统的稳定性也难比文件系统。期望在本文中试图解决所有的问题是不现实的,诸如如何压缩音频数据以减小网络带宽需求或如何通过网络传输音频数据之类的问题,读者需参阅专业著作,本文只讲述如何获得适宜某类需求的原始音频数据。
本文中的示例代码均是一个名为CWaveRecord的录音类的成员函数,该类是一个网络电话程序的核心类。为减小篇幅或简单明了,作了简化处理等。
2      基本过程
MCI按打开设备、配置设备、实现功能(或曰发送命令)、撤销配置、关闭设备的标准次序组织APIs。对于录音编程而言,其要点在于根据音频格式打开对应的设备、配置录音所需的参数(主要是设置数据区以及根据数据接收方式设置回调函数或消息)、按一定次序发送命令给设备、接收数据并配置参数以继续录音、停止录音释放资源、关闭设备等几个步骤上。所需的函数说明于mmsystem.h,引入库是winmm.lib。
2.1    打开设备
调用waveInOpen()打开录音设备,打开成功后函数返回MMSYSERR_NOERROR,而第一个参数返回设备句柄。
调用该函数时,必须指定设备表示符(可能有多个设备)、音频格式以及返回音频数据的方式。
你可以将设备表示符,即第二个参数设为WAVE_MAPPER。这意味着,你不在意具体使用哪个设备,由系统决定。
第三个参数是个WAVEFORMATEX结构指针,对应的结构指定音频格式。一个音频格式结构的例子:
PCMWAVEFORMAT wf_PCM8S11K =
{
       {
                     WAVE_FORMAT_PCM, // PCM格式
                     1,                                       // 单声道
              11025L,                             // 11.025KHZ
                     11025L,                             // 11025字节/s
                     1                                        // 字节对齐
       },
              8                                                 // 8位采样
};
后面的三个参数用于指定获取音频数据的方式:事件方式、线程方式、窗口方式以及回调函数方式。最后一个参数,即第六个参数指定方式,而第四个参数和第五个参数指定该方式所需的信息。
调用示例:
waveInOpen( &m_hWaveIn, dwDeviceID, m_pwf,
 (DWORD)waveInProc, (DWORD)this, CALLBACK_FUNCTION );
该示例使用回调函数方式获取音频数据。其中dwDeviceID通常即为WAVE_MAPPER,m_pwf指向音频格式结构,缺省值即wf_PCM8S11K的地址,waveInProc是回调函数(内部细节后面论述)。值得注意的是,this指针被设为实例数据,这是一个编程小技巧,方便waveInProc调用处理函数。
2.2    配置设备
按指定音频格式成功打开录音设备之后,需要配置录音设备,也即为音频数据分配数据区。需要考虑的第一个问题是数据块的个数和大小。
系统一般在填满一个数据块后将其返回,这意味着大的数据块导致获取数据的频率降低。如果试图通过网络传输这些数据,这意味着传输次数降低,但每次传输的数据量较大,这将导致音频的实时性降低。另外,在网络传输过程中,数据包(指每次发送的UDP或TCP数据包)的开始一般需设置一个信息头,纪录本数据包所含音频数据的长度、录制起始时间、录制时间、发送时间、识别用的标识符以及其他一些信息,方便接受者处理。如果设置的音频数据块太小,比如100字节,将导致低的网络传输效率。这意味着网络将为小量数据启动传输过程,而这小量数据中又有相当一部分属于附加信息,这是不合算的。

下一页
本文共 4 页,第  [1]  [2]  [3]  [4]  页

相关文章:
  • 暂无相关链接
  •  
     
      ·关于我们 ·访客留言 ·友情链接 ·
    粤ICP备08022036号
    站长:ds1010 站长信箱:0101ds@gmail.com

    0101部落开发 @ www.ds0101.net 2007-2008