语音通信系统的设计毕业论文.doc_第1页
语音通信系统的设计毕业论文.doc_第2页
语音通信系统的设计毕业论文.doc_第3页
语音通信系统的设计毕业论文.doc_第4页
语音通信系统的设计毕业论文.doc_第5页
已阅读5页,还剩75页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

盐城工学院本科生毕业设计说明书(2010)语音通信系统的设计毕业论文1 绪 论1.1课题背景及意义 即时聊天工具是一种可以让使用者在网络上实时通讯的工具,大部分的即时通讯工具提供了状态信息的特性,如显示联络人名单,联络人是否在线及能否与联络人交谈等。目前在互联网上受欢迎的即时通讯软件包括百度QQ、MSN Messenger、Yahoo! Messenger、AOL Instant Messenger、NET Messenger Service、Jabber、ICQ等。在本设计中将讨论一种基于MFC Socket的局域网通信工具的设计与实现方法。基于Socket的局域网通信软件可以为局域网提供一种良好、安全、快速的通信机制,在局域网内部通信、教学、讨论等应用中都具有一定的实用价值,它同时很好地诠释了Socket通信的原理。基于Socket的局域网通信软件应用范围广阔,不但可以处理传统的通信需求,而且也能扩展以适应新型的网络应用,如网络教育,数据影音传输等,拥有广泛的应用前景。1.2 课题现状 基于局域网的即时通信工具,实际上是互联网即时通信工具的一个小规模版本,广域网上的即时通信工具,如今一般采用UDP或者 TCP协议体系来实现 ,开发技术已经比较成熟,比如较早的ICQ、MSN Messenger、YAHOO通等国外开发的产品,还有国产的有名的QQ、新浪UC、LAVA-LAVA等,这些工具统统都实现了广域网上的即时通信,尽管都是即时通信,实现了即时聊天,以及文件传输的主要功能,但是也各有各的特色,比如ICQ的巨大客户群,MSN的个性化表情,YAHOO通的易操作性等,而QQ也具有一个相当方便的屏幕截图功能,另外就是,所有上述软件都实现了网络即时的视频,语音聊天功能。这些软件,在使用方面各有特色,在实现方面也各有所长,但由于这些产品正在商业运营阶段,其实现方式属于商业机密,具体细节不可能得知,但是它在大的方面无非就是各种利用各种平台上的网络通信接口,建构基于下层TCP/IP,或者UDP/IP协议的软件产品。在局域网内,这些功能的实现跟广域网相比更加简单,因为局域网的网络结构本身比广域网要简单,但是可以借此理解网络协议,以及网络通信工具的实现原理,所以仍然极具研究价值。1.3 开发平台、开发技术1.3.1 VC+ 6.0 简介 我们通常所说的Visual C+实际上是一个完善的、非常强大的C+程序开发环境,它的名字是 Microsoft Developer Studio 。二者之间的细小差别并不重要,通常这两个术语可以互换。但如果你不围绕Developer Studio 来进行学习,就不能有效地使用Visual C+(Developer Studio 听起来很像Visual Studio , 但它们之间没有关系)。它包含:C+编译器、调试器、应用程序框架生成器、项目管理器、设计和实现菜单等资源的编辑器等等。 Visual C+是一个功能强大的可视化应用程序开发工具,用于Windows环境下32位的应用程序的开发,是计算机界公认的最优秀的应用开发工具之一。在提供可视化的编程方式的同时,Visual C+也适用于编写直接对系统底层操作的程序,生成代码的质量也优于其它的开发工具。在Visual C+环境下,利用Microsoft的基本类库MFC(Microsoft Foundation Class Library),可以使用完全的面向对象的方法来进行Windows 95/98/NT应用程序的开发,使得Windows程序员从大量的复杂劳动中解救出来,体会到真正的程序语言的强大功能和良好的灵活性。 Visual C+编程是一个面向对象的程序设计方法。同传统的结构化程序设计方法相比,它缩短软件的研制时间,提高软件的开发效率,使程序员可以更好地理解和管理庞大而复杂的程序。 面向对象的程序设计吸取了结构化程序设计的精华,它利用了人们根据对事物分类和抽象的倾向,引入了类和对象的概念,具有封装性(数据抽象)、继承和多态的特点。与结构化程序设计不同的是,面向对象程序设计是用类抽象代表现实的实体,用类之间的继承关系表示程序设计的抽象过程。函数只是对数据的操作,没有数据的概念,而类是数据和数据操作的集合,由于面向对象的程序设计方法非常近现实,所以越来越流行。 Visual C+中集成了大量的最新技术,如ActiveX、COM等技术,程序开发人员可以紧紧地把握住软件开发技术发展的方向,开发出功能强大的应用程序。Visual C+还提供了丰富的技术资源,MSDN(Microsoft Develop Network)提供了强大的联机帮助支持,同时还可以通过访问Microsoft的网上站点来获得最新的技术文档。1.3.2 Windows Socket 网络编程 Windows Sockets 规范是以U.C. Berkeley 大学BSD UNIX 中流行的Socket 接口为范例定义了一套开放的、支持多种协议的、Microsoft Windows 下的网络编程接口,并不是一种网络协议。它不仅包含了人们所熟悉的Berkeley Socket 风格的库函数;也包含了一组针对Windows 的扩展库函数,以使程序员能充分地利用Windows 消息驱动机制进行编程。 Windows Sockets 规范本意在于提供给应用程序开发者一套简单的API,使应用程序开发者能够使用,并且网络软件供应商能够实现的一套库函数调用和相关语义。现在的Windows Sockets已经基本上实现了与协议无关,你可以使用Windows Sockets来调用多种协议的功能,但较常使用的是TCP/IP协议。Socket实际在计算机中提供了一个通信端口,可以通过这个端口与任何一个具有Socket接口的计算机通信。应用程序在网络上传输,接收的信息都通过这个Socket接口来实现。 微软为VC定义了Windows Sockets类如CAsyncSocket类和派生于CAsyncSocket 的CSocket类,它们简单易用。2 系统需求分析及要求2.1 语音通信系统需求分析 随着现代计算机技术的不断发展,多媒体已经成为现代计算机不可缺少的功能,而计算机的音频,视频功能是其中最为重要的部分。而随着网络的不断发展,网络已经成为人们最重要的交流方式之一。计算机硬件的更新,非凡是海量存储设备和大容量内存在PC机上的实现,对音频媒体进行数字化处理早已经成为可能。 现在,企业、机关、学校都建立起了局域网。虽然可以通过文件共享的方式进行通讯,但单使用这种方式,非常不方便。在网上邻居里,只能看到机器名,不清楚对方是谁,也不知道对方机器里有什么资源可以共享,尤其当局域网的机器很多时,这种方式就更加麻烦了。而文字聊天方式比较单一缺乏真实感,所以语音通信就有了必要。但是语音传输需要有很大的网络带宽,对于拨号上网用户,语音传输仍然是奢侈品,不过对于局域网和宽带用户来说,是很不错的选择,本系统就是研究的基于局域网的语音传输,并以语音聊天为例给出了实例。语音聊天方式一般有两种,一种是专门的语音聊天室,采用Web方式,B/S结构,另外一中则是类似于QQ、MSN等聊天工具,采用C/S结构。本设计是采用的后者。TCP/IP网络中两个进程间的相互作用的主机模式是客户机/服务器模式。该模式的建立基于以下两点:1、非对等作用;2、通信完全是异步的。客户机/服务器模式在操作过程中采取的是主动请示方式,首先服务器方要先启动,并根据请示提供相应服务。 综上所述,做一个语音通信软件是有必要的,也是能够实现的。2.2 系统的功能要求 在线朋友指的是在所有使用本系统在局域网上进行信息传递的用户。局域网中在线用户之间的语音聊天就是指在线双方互相传递语音信息的功能。a. 在聊天窗口为基础,建立与服务器端的连接。b. 与对方连接以后开始语音聊天。c. 想结束语音聊天时,按结束键就能与对方断开连接,即结束语音聊天。2.3 系统性能要求a. 时间性能要求:在实际应用中由于客户端的大量频繁的访问,服务器响应时间应该尽可能缩短,对于有特殊需求的应用,还要求达到实时响应。b. 存储性能要求:根据应用中的实际情况配置适当容量的存储设备,特别是音频存储设备容量方面要适当得配置。c. 稳定性安全性要求:要求软件尽可能的稳定,对于一般的应用系统,对安全性要求不高,对于特殊的应用,还需要在安全性方面加以保证,所以要相应提高服务器端的配置。3 系统整体设计 要实现点对点语音通信,原理非常简单,只要针对一个点实现话音的实时采集、处理、播放,同时能进行可靠的传送和接收,这样两点一连便可通话。对于前者,采用Windows 的低层音频服务比较合适,因为低层音频服务中的回调机制为我们提供了很大的方便。当应用程序不断向设备驱动程序提供音频数据时,设备驱动程序控制音频设备在后台完成录音和放音的具体操作,通过回调机制,我们又可以检测到什么时候用完一个数据块,并及时传送下一个数据块,从而保证了声音的连续,有了这种实时采集、回放功能后,接下来的工作就是在网络上传送话音数据。在点对点网络传输方面,选择面向连接的TCP/IP协议,TCP/IP传输协议自动处理分组丢失和交付失序问题,这样我们不用为这些问题操心,只需很好地利用这个连接,在采集话音回放之前一方面将自己的话音传给网络,另一方面接收网络传来的话音,这样便实现了点对点语音通信。其模块框图如图 3-1所示,总体结构图为图3-2所示。语音通信系统音频采集音频回放网络传输音频编/解码图 3-1 模块框图图 3-2 总体结构图一个完整的音频通信系统程序要完成以下工作:发送端完成音频采集、压缩编码、码流发送等;接收端则要完成码流接收、解码恢复、音频回放等。其总体程序流程图如图3-3所示。程序开始启动音频输入/输出呼叫对方连接成功连接失败压缩编码音频输出音频输入Socket发送网络Socket 接收程序退出图 3-3 总体程序流程4 各模块详细设计4.1音频编/解码4.1.1音频编/解码介绍 自然界中的声音非常复杂,波形极其复杂,通常我们采用的是脉冲代码调制编码,即PCM编码。PCM通过抽样、量化、编码三个步骤将连续变化的模拟信号转换为数字编码。 a. 采样率和采样大小(位/bit)。 声音其实是一种能量波,因此也有频率和振幅的特征,频率对应于时间轴线,振幅对应于电平轴线。波是无限光滑的,弦线可以看成由无数点组成,由于存储空间是相对有限的,数字编码过程中,必须对弦线的点进行采样。采样的过程就是抽取某点的频率值,很显然,在一秒中内抽取的点越多,获取得频率信息更丰富,为了复原波形,一次振动中,必须有2个点的采样,人耳能够感觉到的最高频率为20kHz,因此要满足人耳的听觉要求,则需要至少每秒进行40k次采样,用40kHz表达,这个40kHz就是采样率。我们常见的CD,采样率为44.1kHz。光有频率信息是不够的,我们还必须获得该频率的能量值并量化,用于表示信号强度。量化电平数为2的整数次幂,我们常见的CD位16bit的采样大小,即2的16次方。采样大小相对采样率更难理解,因为要显得抽象点,举个简单例子:假设对一个波进行8次采样,采样点分别对应的能量值分别为A1-A8,但我们只使用2bit的采样大小,结果我们只能保留A1-A8中4个点的值而舍弃另外4个。如果我们进行3bit的采样大小,则刚好记录下8个点的所有信息。采样率和采样大小的值越大,记录的波形更接近原始信号。 b. 有损和无损 根据采样率和采样大小可以得知,相对自然界的信号,音频编码最多只能做到无限接近,至少目前的技术只能这样了,相对自然界的信号,任何数字音频编码方案都是有损的,因为无法完全还原。在计算机应用中,能够达到最高保真水平的就是PCM编码,被广泛用于素材保存及音乐欣赏,CD、DVD以及我们常见的WAV文件中均有应用。因此,PCM约定俗成了无损编码,因为PCM代表了数字音频中最佳的保真水准,并不意味着PCM就能够确保信号绝对保真,PCM也只能做到最大程度的无限接近。我们而习惯性的把MP3列入有损音频编码范畴,是相对PCM编码的。强调编码的相对性的有损和无损,是为了告诉大家,要做到真正的无损是困难的,就像用数字去表达圆周率,不管精度多高,也只是无限接近,而不是真正等于圆周率的值。 c. 音频压缩技术 要算一个PCM音频流的码率是一件很轻松的事情,采样率值采样大小值声道数 bps。一个采样率为44.1KHz,采样大小为16bit,双声道的PCM编码的WAV文件,它的数据速率则为 44.1K162 =1411.2 Kbps。我们常说128K的MP3,对应的WAV的参数,就是这个1411.2 Kbps,这个参数也被称为数据带宽,它和ADSL中的带宽是一个概念。将码率除以8,就可以得到这个WAV的数据速率,即176.4KB/s。这表示存储一秒钟采样率为44.1KHz,采样大小为16bit,双声道的PCM编码的音频信号,需要176.4KB的空间,1分钟则约为10.34M,这对大部分用户是不可接受的,尤其是喜欢在电脑上听音乐的朋友,要降低磁盘占用,只有2种方法,降低采样指标或者压缩。降低指标是不可取的,因此专家们研发了各种压缩方案。 d. 频率与采样率采样率表示了每秒对原始信号采样的次数,我们常见到的音频文件采样率多为44.1KHz,这意味着什么呢?假设我们有2段正弦波信号,分别为20Hz和20KHz,长度均为一秒钟,以对应我们能听到的最低频和最高频,分别对这两段信号进行40KHz的采样,我们可以得到一个什么样的结果呢?结果是:20Hz的信号每次振动被采样了40K/20=2000次,而20K的信号每次振动只有2次采样。显然,在相同的采样率下,记录低频的信息远比高频的详细。这也是为什么有些音响发烧友指责CD有数码声不够真实的原因,CD的44.1KHz采样也无法保证高频信号被较好记录。要较好的记录高频信号,看来需要更高的采样率,于是有些朋友在捕捉CD音轨的时候使用48KHz的采样率,这是不可取的!这其实对音质没有任何好处,对抓轨软件来说,保持和CD提供的44.1KHz一样的采样率才是最佳音质的保证之一,而不是去提高它。较高的采样率只有相对模拟信号的时候才有用,如果被采样的信号是数字的,请不要去尝试提高采样率。 e. 流特征 随着网络的发展,人们对在线收听音乐提出了要求,因此也要求音频文件能够一边读一边播放,而不需要把这个文件全部读出后然后回放,这样就可以做到不用下载就可以实现收听了。也可以做到一边编码一边播放,正是这种特征,可以实现在线的直播,架设自己的数字广播电台成为了现实。4.1.2 PCM编码和WAVE音频格式 a. PCM编码 PCM 脉冲编码调制是Pulse Code Modulation的缩写。前面的文字我们提到了PCM大致的工作流程,我们不需要关心PCM最终编码采用的是什么计算方式,我们只需要知道PCM编码的音频流的优点和缺点就可以了。PCM编码的最大的优点就是音质好,最大的缺点就是体积大。我们常见的Audio CD就采用了PCM编码。 b. WAVE 这是一种经典的音频文件格式,由微软开发。WAV是一种文件格式,符合 PIFF Resource Interchange File Format规范。所有的WAV都有一个文件头,这个文件头音频流的编码参数。WAV对音频流的编码没有硬性规定,除了PCM之外,还有几乎所有支持ACM规范的编码都可以为WAV的音频流进行编码。很多朋友没有这个概念,我们拿AVI做个示范,因为AVI和WAV在文件结构上是非常相似的,不过AVI多了一个视频流而已。我们接触到的AVI有很多种,因此我们经常需要安装一些Decode才能观看一些AVI,我们接触到比较多的DivX就是一种视频编码,AVI可以采用DivX编码来压缩视频流,当然也可以使用其他的编码压缩。同样,WAV也可以使用多种音频编码来压缩其音频流,不过我们常见的都是音频流被PCM编码处理的WAV,但这不表示WAV只能使用PCM编码,MP3编码同样也可以运用在WAV中,和AVI一样,只要安装好了相应的Decode,就可以欣赏这些WAV了。 在Windows平台下,基于PCM编码的WAV是被支持得最好的音频格式,所有音频软件都能完美支持,由于本身可以达到较高的音质的要求,因此,WAV也是音乐编辑创作的首选格式,适合保存音乐素材。因此,基于PCM编码的WAV被作为了一种中介的格式,常常使用在其他编码的相互转换之中,例如MP3转换成WMA。 c. PCM编码的WAV PCM编码的WAV文件是音质最好的格式,Windows平台下,所有音频软件都能够提供对它的支持。Windows提供的WinAPI中有不少函数可以直接播放wav,因此,在开发多媒体软件时,往往大量采用wav,用作事件声效和背景音乐。PCM编码的wav可以达到相同采样率和采样大小条件下的最好音质,因此,也被大量用于音频编辑、非线性编辑等领域。 其特点是音质非常好,被大量软件所支持。 适用于多媒体开发、保存音乐和音效素材。所以本设计选用WAV格式的音频进行录制和播放4.1.3 G729编/解码本设计使用G729编解码标准对音频进行音频编解码,在Visual C+环境中直接调用G729库来对音频数据进行处理。 G729编/解码标准20世纪80年代末,为满足长途通信的需求,ITU制订8kbps的高质量低延时的语音编码标准。a. 技术指标: 采样率 8kHz、码率 8kbps。b. 技术特点: 采用代数码本,码书简单、无需存储,恢复音质清晰;分析窗采用混合窗,LSP参数采用两级矢量量化;基音分析采用开环基音分析和自适应码本搜索结合,低运算复杂度、高精度;采用10ms分析帧,编码时延小。c. 应用状况: 被广泛应用于IP电话、视讯电话、视讯会议系统等。d. 技术框架:如图 4-1所示。图4-1 G729编/解码技术框架 G729编/解码 C+实现核心代码/音频解码#pragma comment(lib,G729a)/构造函数CAudioCode:CAudioCode()va_g729a_init_encoder();/初始化编码器va_g729a_init_decoder();/初始化解码器/析构函数CAudioCode:CAudioCode()/编码音频数据BOOL CAudioCode:EncodeAudioData(char *pin,int len,char* pout,int* lenr)/编码成功与否标记BOOL bRet=FALSE;/无效输入或输出if(!pin|len!=SIZE_AUDIO_FRAME|!pout)goto RET;/分块进行编码va_g729a_encoder(short*)pin,(BYTE*)pout);va_g729a_encoder(short*)(pin+160),(BYTE*)pout+10);va_g729a_encoder(short*)(pin+320),(BYTE*)pout+20);va_g729a_encoder(short*)(pin+480),(BYTE*)pout+30);va_g729a_encoder(short*)(pin+640),(BYTE*)pout+40);va_g729a_encoder(short*)(pin+800),(BYTE*)pout+50);/编码长度if(lenr)*lenr=SIZE_AUDIO_PACKED;/编码成功标记bRet=TRUE;RET:/返回return bRet;/音频解码BOOL CAudioCode:DecodeAudioData(char *pin,int len,char* pout,int* lenr)/解码成功与否标记BOOL bRet=FALSE;/无效输入或输出if(!pin|len!=SIZE_AUDIO_PACKED|!pout)goto RET;/分块解码va_g729a_decoder(BYTE*)pin,(short*)(pout),0);va_g729a_decoder(BYTE*)pin+10,(short*)(pout+160),0);va_g729a_decoder(BYTE*)pin+20,(short*)(pout+320),0);va_g729a_decoder(BYTE*)pin+30,(short*)(pout+480),0);va_g729a_decoder(BYTE*)pin+40,(short*)(pout+640),0);va_g729a_decoder(BYTE*)pin+50,(short*)(pout+800),0);/解码长度if(lenr)*lenr=SIZE_AUDIO_FRAME;/设置解码成功标记bRet=TRUE;RET:return bRet;4.2 音频采集及回放 本设计采用基于WaveX 低级音频API 采集音频及实时播放的技术。利用双/ 多缓冲技术和网络拥塞控制策略可很好的控制音频的实时性和连续性。双/ 多缓冲技术可以很好的实现声音的快速连续采集和实时顺畅播放。4.2.1 方案选择音频的采集WINDOWS 下音频的采集,播放有三种模式:a. 通过高级音频函数、媒体控制接口MCI1 、2 设备驱动程序;b. 低级音频函数MIDI Mapper 、低级音频设备驱动(WaveX API );c. 利用DirectX 中的DirectSound 。使用MCI 的方法极其简便,灵活性较差,因此较难推广;使用低级音频函数的方法相对来说难一点,但是能够对音频数据进行灵活的操控;而采用DirectSound 的方法,控制声音数据灵活,效果比前二者都好,但实现起来是三者中最难的。其三者的关系如图4-2所示。图 4-2 三者关系低层音频服务及重要的数据结构低级音频服务控制着不同的音频设备,这些设备包括 WAVE,MIDI 和辅助音频设备。 如果想编写一个功能较强大的音频处理程序,那就必须使用低级音频函数和多媒体文件I/O来控制音频设备的输入和输出。因为低级音频函数可直接与音频驱动程序交互,通过窗口消息或回调(CALL BACK)函数来管理音频数据块的记录和播放,控制非常灵活。重要的一点是,低级音频函数为我们提供了一个设备无关的接口。低层音频服务及重要的数据结构低级音频服务控制着不同的音频设备,这些设备包括 WAVE,MIDI 和辅助音频设备。低级音频服务包括如下内容: a. 查询音频设备;b. 打开和关闭设备驱动程序;c. 分配和准备音频数据块;d. 管理音频数据块;e. 应用MMTIME 结构; f. 处理错误。4.2.2 相关数据结构a. WaveX 低级音频函数的相关声明和定义在mmsystem.h 头文件和Winmm.lib 库中。所以如果程序中用到这些函数,必须包含mmsystem.h 这个头文件,同时导进Winmm.lib 库。如下:#include mmsystem.h#pragma comment(lib,Winmm.lib)b. 声音在采集和播放的时需要有一些统一的格式,包括音频格式类型,声道,采样率等信息。下面的数据结构具体描述了该格式:wFormatTag 是音频格式类型,nChannels 是声道数,nSamplesPerSec 是采样频率,nAvgBytesPerSec 是每秒钟的字节数,nBlockAlign 是每个样本的字节数,wBitsPerSample 是每个样本的量化位数,cbSize 是附加信息的字节大小。c. 音频数据块有一个头结构,这个结构包含了音频数据缓冲的地址,大小,已录音数据大小等信息和其他各种控制标志。这个结构适用于音频的输入(录音)和输出(播放)缓冲中。详细信息包括:lpData 是指定的缓冲块地址,dwBufferLength 是指定的缓冲块大小,dwBytesRecorded 是已录音数据大小,dwUser 是用户数据,dwFlags 是控制标志,表明缓冲的使用状态,dwLoops 是音频输出时缓冲数据块循环的次数,lpNext 和reserved 是系统保留数据。在程序实现时,通过设置或修改这个结构的相关参数来实现对音频输入和输出缓冲区的控制。4.2.3 音频采集4.2.31 音频采集原理 电脑依靠声卡来处理声音,Windows把声卡看作是录音和放音设备的组合体,录音时首先要准备一个录音队列,队列中包含录音的基本参数,比如录音数据缓冲区的地址、缓冲区的大小等,为了使录音过程平滑的进行,队列中至少包含两个以上数据缓冲区,当一个缓冲区录完后,Windows系统会给应用程序发送一个录音结束的消息,并自动开始转入下一个缓冲区进行录音,应用程序收到该消息后应该释放含有录音数据的队列,并取出该队列所指向的缓冲区的声音数据,然后将该缓冲区再次加入录音队列,以便继续进行录音。Windows就是这样利用这些数据缓冲区进行周而复始的录入工作。 采集声音时,缓冲满了会有一个消息,程序在响应这个消息需要几毫秒几十毫秒甚至更多的时间,假设为Xms,如果只使用一个缓冲,程序必须在响应完该消息才再次采集声音,那么在这Xms 的时间里,没有采集到任何声音;声音的播放也是一样的道理,这样声音就会不连续。因此双缓冲或多缓冲技术是必要的,让输入和输出设备可以循环使用这些缓冲,当程序在响应某块缓冲数据已满或播放完毕消息时,声卡可以继续往下一块缓冲添加数据或播放下一块缓冲的数据,如此循环保障声音的连续性。其基本原理图如图4-3所示。 图 4 -3 音频采集原理图4.2.32 音频采集具体流程 在使用音频设备之前,必须打开设备驱动程序。为可靠起见,在播放和记录音频之前,要确定系统音频设备的能力。在用完之后必须关闭音频设备。音频采集流程图如图4-4所示。具体流程如下: a. 查询设备数目和能力 因为计算机的硬件和性能各不相同,所以在音频采集前,首先要检测有无音频录制设备。通过使用waveOutGetNumDevs和waveOutGetDevCaps来获取波形输出设备的个数和能力。只有在确定设备存在之后,才可以打开设备、使用设备。 b. 打开波形输出设备 在使用录入设备前,必须打开音频录入设备。这里可以调用waveOutOpen为进行重放操作打开特定的波形设备。该函数打开与指定的设备相关联的设备,并以给出指定内存句柄的方法返回打开波形设备的句柄。 当有多种波形输出设备时,建议使用WAVE_MAPPER常数作为设备ID,这使waveOutOpen函数会自动挑选最适合播放给定的数据格式的设备。 c. 准备音频数据块 在录制时音频录入会产生大量的数据,所以我们要为这些数据分配缓冲区。在波形重放之前,要准备好音频数据块。将数据块传递给设备驱动程序就实现了重放。使用的函数是waveOutPerpareHeader。 d. 开始录制 经过以上步骤后,一切准备就绪,调用WaveInStart就可以开始录制。当一个缓冲区使用完后音频驱动程序就调用上述在打开录入设备时指定的回调函数。在用完数据块之后,必须用waveOutUnPrepareHeader函数来清除对波形数据块的准备。再将数据读出,然后再把该缓冲区添加给驱动程序。 图4-4 音频采集流程图4.2.33音频采集核心代码/ WaveIn.CPPclass CWaveInpublic:/线程处理static DWORD WINAPI AudioInThreadProc(LPVOID lpParameter);public:/获取数据virtual void GetData(char *pBuffer,int iLen);/启动录音BOOL StartRec();/停止录音BOOL StopRec();/获取实例inline DWORD GetInstance();/获取采样位数inline WORD GetBit();/获取采样速率inline DWORD GetSample();/获取频道数inline WORD GetChannel();/设置采样位数inline void SetBit(WORD wBit);/设置采样速率inline void SetSample(DWORD dwSample);/设置采样速率inline void SetChannel(WORD wChannel);/获取错误信息inline MMRESULT GetLastMMError();CString GetLastErrorString();/构造函数CWaveIn();/析构函数virtual CWaveIn();protected:/打开设备BOOL OpenDev();/关闭设备BOOL CloseDev();/停止线程BOOL StopThread();/启动线程BOOL StartThread();/准备缓存BOOL PerPareBuffer();/释放缓存BOOL FreeBuffer();/开始录音BOOL OpenRecord();/结束录音BOOL CloseRecord();protected:/用户实例数据static DWORD s_dwInstance;protected:/频道数WORD m_wChannel;/采样速率DWORD m_dwSample;/采样位数WORD m_wBit;protected:/音频输入设备句柄HWAVEIN m_hIn;/函数调用返回信息MMRESULT m_mmr;/回调函数指针DWORD m_dwAudioInId;/线程句柄HANDLE m_hAudioIn;/WAVEHDR结构缓存指针WAVEHDR* m_pHdr;/线程启动标志BOOL m_bThreadStart;/设备打开标记BOOL m_bDevOpen;/内存分配标记BOOL m_bAllocBuffer;/录音开始标记BOOL m_bRecord;4.2.4 音频回放4.2.41音频回放原理 经过处理过的语音数据通过音频处理传送到这个模块,当接收到语音数据以后它将经过录音的语音数据进行放音,然后把内存释放出来以备保存其他缓冲区里保存的声源信息。由于声音数据具有很强的前后相关性,数据量大、实时性强,又由于声音是连续的,通常把其称之为连续型时基媒体类型,因此需要释放内存。当缓冲区接收到声源以后要是内存不够的话就不能及时把全部语音数据保存并传送,所以经过这个模块以后就得把录音内存释放掉,好让上一个模块及时得到完成。其基本原理图如图4-5所示。 图4-5 音频回放原理图4.2.42 音频回放具体流程 缓冲区中数据播放完成后系统会向应用程序发送放音完成的消息,应用程序可以重复前面的工作,先释放完成的队列,然后向缓冲区加入新的声音数据,并再次将该缓冲区加入放音队列,让该队列继续工作。音频回放流程图如图4-6所示。具体流程如下: a. 管理波形重放 在使用低级音频函数播放音频时,应用程序必须不断地向设备驱动程序提供数据块,直到播放结束。WINDOWS提供两种方法管理波形重放:一是使用窗口消息管理,二是使用低级回调函数管理。另外,通过使用waveOutPause、waveOutRestart和waveOutReset来进行暂停、重新启动和停止播放。b. 关闭波形设备 用完设备之后,必须调用waveOutClose函数关闭波形输出设备,以便其他程序可以使用设备。图4-6 音频回放流程图4.2.43音频回放核心代码class CWaveOut public:/线程处理static DWORD WINAPI AudioOutThreadProc(LPVOID lpParameter);public:/根据文件设置格式BOOL SetFormatByFile(CString file);/播音BOOL Play(char* buf,UINT uSize);/开始播音BOOL StartPlay();/停止播音BOOL StopPlay();/获取缓存数目inline int GetBufferNum();/减少缓存数目inline void BufferSub();/增加缓存数目inline void BufferAdd();/获取实例inline DWORD GetInstance();/获取采样位数inline WORD GetBit();/获取采样速率inline DWORD GetSample();/获取频道数inline WORD GetChannel();/设置采样位数inline void SetBit(WORD wBit);/设置采样速率inline void SetSample(DWORD dwSample);/设置频道数inline void SetChannel(WORD wChannel);/获取错误信息inline MMRESULT GetLastMMError();CString GetLastErrorString();/构造函数CWaveOut();/析构函数virtual CWaveOut();protected:/打开设备BOOL OpenDev();/关闭设备BOOL CloseDev();/停止线程BOOL StopThread();/启动线程BOOL StartThread();protected:/用户实例数据static DWORD s_dwInstance;protected:/频道数WORD m_wChannel;/采样速率DWORD m_dwSample;/采样位数WORD m_wBit;protected:/函数调用返回信息MMRESULT m_mmr;/播音设备句柄HWAVEOUT m_hOut;/线程句柄HANDLE m_hAudioOut;/回调函数指针DWORD m_dwAudioOutId;/缓存数目int m_iBufferNum;/重要部分(critical section)CCriticalSection m_csLock;/线程启动标志BOOL m_bThreadStart;/播音设备打开标志BOOL m_bDevOpen;/线程处理friend DWORD WINAPI AudioOutThreadProc(LPVOID lpParameter);4.3 网络的传送和接收 网络的传输和接收部分是本设计最重要的模块,对于主机1传送到主机2的音频数据信息这条数据通路,主机1为客户端,主机2为服务端;而对于主机2传送到主机1的音频数据信息这条数据通路,主机2为客户端,主机1为服务器端。双方通话时,主机1和主机2同时既处于服务器状态又处于客户端状态,即通话状态。主机1呼叫主机2时,主机1进入客户端状态,主机2收到呼叫信息,进入服务器端状态,若主机2同意通话,则两机都进入通话状态,双方可以通过上述两条数据通路进行网络通话,若有一机挂断,两机都返回侦听状态,等待呼叫或被呼叫。4.3 .1 TCP/IP 体系结构与特点4.3 .1.1 TCP/IP体系结构 TCP/IP协议实际上就是在物理网上的一组完整的网络协议。其中TCP是提供传输层服务,而IP则是提供网络层服务。TCP/IP包括以下协议:结构图如图4-7 图 4-7 TCP/IP结构图 IP:网间协议(Internet Protocol) 负责主机间数据的路由和网络上数据的存储。同时为ICMP、TCP、UDP提供分组发送服务。用户进程通常不需要涉及这一层。ARP: 地址解析协议(Address Resolution Protocol)此协议将网络地址映射到硬件地址。RARP: 反向地址解析协议(Reverse Address Resolution Protocol)此协议将硬件地址映射到网络地址。ICMP: 网间报文控制协议(Internet Control Message Protocol),此协议处理信关和主机的差错和传送控制。TCP: 传送控制协议(Transmission Control Protocol),这是一种提供给用户进程的可靠的全双工字节流面向连接的协议,它要为用户进程提供虚电路服务,并为数据可靠传输建立检查。(大多数网络用户程序使用TCP)UDP: 用户数据报协议(User Datagram Protocol),这是提供给用户进程的无连接协议,用于传送数据而不执行正确性检查。FTP: 文件传输协议(File Transfer Protocol),允许用户以文件操作的方式(文件的增、删、改、查、传送等)与另一主机相互通信。SMTP: 简单邮件传送协议(Simple Mail Transfer Protocol),SMTP协议为系统之间传送电子邮件。TELNET:终端协议(Telnet Terminal Procotol),允许用户以虚终端方式访问远程主机。HTTP: 超文本传输协议(Hypertext Transfer Procotol),TFTP: 简单文件传输协议(Trivial File Transfer Protocol)。4.3 .1.2 TCP/IP特点 TCP/IP协议的核心部分是传输层协议(TCP、UDP),网络层协议(IP)和物理接口层,这三层通常是在操作系统内核中实现。因此用户一般不涉及。编程时,编程界面有两种形式:一、是由内核心直接提供的系统调用;二、使用以库函数方式提供的各种函数。前者为核内实现,后者为核外实现。用户服务要通过核外的应用程序才能实现,所以要使用套接字(socket)来实现。Socket与TCP/IPc协议的关系如图4-8图 4-8 Socket与TCP/IPc协议4.3 .1.3 Windows Socket VC+对网络编程的支持有socket支持,Winlnet支持,MAPI和ISAPI支持等。其中Windows Sockets API是TCP/IP网络环境里,也是Internet上进行开发最为通用的API。最早美国加州大学Berkeley分校在UNIX下为TCP/IP协议开发了一个API,这个API就是著名的Berkeley Socket接口(套接字)。在桌面操作系统进入Windows时代后,仍然继承了Socket方法。从表4-1中可以看出,主要的WinSock API函数。表4-1 WinSock API函数函数功能WSAStartup()连结应用程序与 Windows Sockets DLL 的第一个函数WSACleanup()结束 Windows Sockets DLL 的使用socket()建立Socketclosesocket()关闭某一Socketbind()将一本地地址与一个SOCKET描述字连接在一起listen()设定 Socket 为监听状态,准备被连接accept()接受某一Socket的连接要求,以完成面向连接的客户端连接请求。connect()要求连接某一Socket到指定的网络上服务端recv()从面向连接的 Socket 接收信息send()使用面向连接的 Socket 发送信息WSAAsyncSelect()要求某一 Socket 有事件 (event) 发生时通知使用者 套接字(Socket)是一种双向的通信接口,可以通过这个端口与任何一个具有Socket端口的计算机通信,套接字是网络通信的基础。Socket在Windows以句柄的形式被创建。使用Socket进行网络通信必须包含下面的几种信息:双方认可的协议,本地主机的IP地址,本地进程的协议端口,对方主机的IP地址,对方进程的协议端口。 Socket可分为:数据报套接字(Datagram Sockets) 对于在TCP/IP上实现的WinSock,数据报套接字使用用户数据报协议(UDP)。数据报套接字提供了一种不可靠的、非连接的数据包通信方式。流式套接字(Stream Sockets)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论