Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1087410
  • 博文数量: 282
  • 博客积分: 10865
  • 博客等级: 上将
  • 技术积分: 2480
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-12 12:35
文章存档

2017年(1)

2016年(3)

2015年(10)

2014年(12)

2013年(5)

2012年(10)

2011年(29)

2010年(3)

2008年(13)

2007年(92)

2006年(104)

我的朋友

分类: 系统运维

2006-06-14 15:14:57

 :主要介绍基于中等带宽网络的语音通讯的原理、关键技术和实现方法,给出了一般的开发过程和具体开发实例。重点介绍自定义的IP电话信令系统的原理和实现过程。
    关键词:IP电话;语音通信;CODECs;Winsock控件

1 引 言
  IP电话是近些年网络在实时通讯领域的一个重要应用。利用IP电话系统在实现通话功能的基础上,还可以提供增值服务,如视频电话、高保真的立体声电话会议、IP电话会议、远程电话教学应用等。
  针对局域网的网络带宽和用户需求,开发出一套基于局域网用户的网络电话系统。由于局域网内的网络带宽可以达到10 Mb/s甚至是100 Mb/s的速率,因此,只要选择了恰当的压缩算法,实现高质量的语音通讯是没有问题的。而且在使用局域网的用户中,计算机的普及率也是非常高的。这样的系统在学校、企事业单位的局域网内将有非常好的推广价值。

2 关键技术
  本文所讨论IP电话指的是计算机到计算机形式的IP语音电话。
  为了实现计算机到计算机的语音通话,至少需要解决以下两方面的问题:
    (1)双方都知道对方的网络地址。
    (2)同时运行IP电话语音通讯程序。
  解决方案是:通过在系统中驻留一个资源占用率小的管理程序来监听呼叫请求;在建立通话时再调用IP电话通讯程序。
    2.1 语音通讯
  语音通讯的基本原理是:对模拟语音信号经过模数转换,进行编码压缩后,按一定的打包规则将压缩帧转换成IP数据包通过数据网进行传输,在目的地经过数据解压、数模转换复原成话音,从而达到语音通信的目的。这部分是IP电话的难点,也是需要不断进行改进的地方。总的目标是在保证通话服务质量(QoS)的前提下,尽可能减少网络和系统资源的占用。在广域网语音通讯中,现有技术还不能完全达到二者兼顾。所幸对于局域网用户,现有的技术已经勉强可以达到要求。
    2.1.1 语音采集与数据压缩
  语音的采集采样率的大小直接决定语音的清晰度和采集的原始数字数据量的大小。语音采集的原理是通过在离散的时间间隔采样原始声音并记录每次采样的数字来表示和重建声音波形。采集的声音数据的格式有很多标准,软件的设计中一般采用波形数据的格式。Windows系统中可以采用WAVE_FORMAT_PCM即PCM(脉冲编码调制)格式,其采样率可以为数据流采样后需要对音频数据进行压缩。采用什么样的压缩算法决定了压缩率的大小,这也是整个网络语音通信技术的核心和最关键的技术之一。IP电话网关为主的IP语音通信主要使用ITU定义的几个语音编码标准:G723.1,G728和G729。他们采用的都是混合编码的方法,如G.729语音压缩采用的算法是共轭结构的代数码激励线形预测(CSACELP),是基于CELP编码模型的算法。
  CODEC是一小段用于压缩(Compress)及解压缩(DECompress)数据流的代码。CODECs可以是由操作系统本身附带的几种标准的CODECs,如:DSPGroup TrueSpeech CODEC和MSG723.1 CODEC等,也可由系统中所安装的应用程序安装其他的CODECs。微软的Windows操作系统中,所有安装的CODECs由音频压缩管理器(ACM)管理。
    2.1.2 数据包传输
  压缩后打包的音频数据需要通过IP协议在网络中传输,但首先必须在传输层协议TCP或UDP中选择其一。UDP包不具备TCP包复杂的可靠性与控制机制,当强调传输性能(例如延时特性)而不是传输的完整性时,如:音频和多媒体应用,UDP是较好的选择。
  Winsock控件封装了许多网络传输所用到的API函数。通过Winsock控件,使网络编程变得轻松。
    2.2 信令系统
  决定IP电话可用性的关键是要使双方能够知道对方的IP地址,这并不太容易做到。以往的IP电话往往将重点集中于语音通讯模块的优化而忽视了信令系统的改进。为了得到对方IP,可以通过其他通讯方式,例如E-Mail ,OICQ信使服务、普通电话等办法获得,但这样就减少了系统的易用性;当然,也可以设置一个固定的“通话服务器”,采用类似于电信电话的“交换机”方式进行通话“路由”。但这样做势必造成服务器的负荷很重。此外,集中通过中转也必然造成服务器拥塞和丢包,通话延迟和语音质量难以改进。  
    通过设置一个信令服务器的方式综合以上两种方式的优缺点。用户通话程序工作于半客户机状态,信令服务器负责客户的集中呼叫。当某一个客户呼叫,服务器负责中转呼叫,当被叫客户响应呼叫并应答后,自主于呼叫方进行通话而不必经过信令服务器,这样,大幅度地减少了服务器的数据量。有了集中的信令服务器,也便于客户的管理,还可进行广播消息的发布。
  信令与驻留的管理程序相互配合,共同实现IP电话的基本通话逻辑和其他附加功能。信令系统可以设计得很复杂,也可以很简单,但必须完成以下功能:呼叫、应答、指示通话、挂断等基本功能。

3 程序设计实现[1~3]
  基于以上的技术和所在单位的网络资源,笔者初步成功地开发了基于局域网的语音通讯软件。软件平台为Windows 98/ME/2000/XP;硬件平台为含全双工声卡、麦克风和音响的多媒体PC;开发工具为VisualBasic 6.0,VisualC++6.0和Delphi6.0。下面介绍具体的开发过程。
    3.1 整体结构
  本系统从逻辑上分为2个部分:客户端和服务器端。
    客户端与服务器端之间的关系如图1所示。

  直接呼叫是指输入对方的IP地址,然后向其发出呼叫请求;而通过服务器呼叫指的是向服务器提交要呼叫的用户名,由服务器在数据库中查找用户,如果该用户在线的话将该用户的IP返回给客户端,然后再由客户端发出呼叫请求。
  服务器端的数据库中包含了所有用户的资料。例如用户的密码、最后一次登录时使用的IP地址、该用户是否在线、该帐号是否被禁用等信息。服务器端程序利用Winsock控件来监听客户端发来的请求,对接收到的客户端发来的请求进行处理,提取出命令字及参数,按照定义好的命令字完成相应的工作。
  服务器完成的任务基本上都是被动的,大部分是响应客户端发出的请求。但系统也提供了一个服务器端向客户端发消息的功能,可选择发送到任一当前在线的用户,也可以选择发送到所有在线用户。
  如图2所示,客户端由2个主要模块组成:系统驻留模块、语音通讯模块。
    整个系统最重要的模块为系统驻留模块。在客户94端登录时,该模块把登录请求提交给服务器;在成功登录服务器之后呼叫服务器上的用户时,该模块负责向服务器提交查询用户请求。从服务器返回的消息也交给该模块处理。在直接呼叫时,也是通过该模块建立连接。当连接建立起来,还是由该模块调用语音通讯模块来实现语音通讯。而且以后对系统进行二次开发、插件接口也是基于该模块的接口定义而开发的。

  语音通讯模块负责建立起连接之后的语音通讯功能。该模块从声卡采集音频数据并压缩,然后根据从系统驻留模块获得的IP地址参数来把数据流发送到对方主机。同时该模块还负责对接收到的语音数据流进行解压缩并利用声卡播放出来的任务。
  服务器端和客户端系统驻留模块使用VB开发,语音通讯模块和部分应用界面使用Delphi和VC开发。这是综合考虑了VB在界面和数据库设计方面的优越性,以及VC和Delphi在系统应用程序开发上的高效率后做出的选择。
    3.2 信令系统的实现
  在C/S模式中,消息命令字起到了非常重要的作用,服务器端与客户端、客户端与客户端之间通过发送以消息命令字开头的包含指定消息的字符串来实现沟通。收到指定的消息命令字就去执行该消息命令字对应的操作。消息命令字可以是以字节形式组成的,也可以是以比特位形式组成的。本系统采用的是用固定长度的字符串组成的消息命令字,通过定义特殊的消息命令字(信令)来控制系统工作。为避免混淆规定:服务器端可以处理的信令长度为4个字符;客户端可以处理的信令长度为6个字符。
    以下是系统自定义的部分信令格式及其说明:  
    (1)服务器端接收来自客户端的消息,命令字长度为4 B。参数在命令字之后,并且用“/”分开。
    LGIN:用户登录服务器的命令字。
  消息格式:LGIN/客户端主机地址/用户名/密码/新密码(如果为空则表示不修改密码)
    使用说明:如果服务器收到该命令字,将处理用户的登录请求。对客户端提供的用户名和密码进行验证,并返回验证结果。如果用户提供了新密码,则在验证通过的前提下,将该用户密码修改为新密码。
    CALL:通过服务器来呼叫其他用户的命令字。  
    消息格式:CALL/客户端主机地址/用户名/呼叫的用户名
  使用说明:如果服务器收到该命令字,将处理用户的呼叫请求。服务器对客户端所呼叫的用户状态进行查询,并返回查询的结果。
    QUIT:用户从服务器退出的命令字。消息格式:QUIT/客户端主机地址/用户名  使用说明:如果服务器收到该命令字,将处理用户的退出请求。
  (2)客户端接收来自服务器端的消息,命令字长度为6 B。参数在命令字的后面。
    REJECT:用户名或密码错误的命令字。  
    使用说明:该命令字没有参数。为了防止用户进行暴力破解,所以不提供是用户名错误还是密码错误的消息。
    ACCEPT:登录被接纳的命令字。
  使用说明:当客户端提供的用户名和密码均正确,而且该帐号没有被禁用的时候,服务器返回该命令字,表示客户端的登录请求已经被接纳。
  (3)客户端接收来自客户端的消息,命令字长度为6 B。参数在命令字之后,并且用“/”分开。
    RECEIV:接收到请求的命令字。
    消息格式:RECEIV/客户端主机地址/用户名  
    使用说明:如果客户端收到该命令字,则表示用户发送的请求已经成功的到达对方。确定网络传输没有问题。
    ANSWER:接受语音通话请求的命令字。消息格式:ANSWER/客户端主机地址/用户名  使用说明:如果客户端收到该命令字,则表示语音通话的请求已经被接受。客户端开始调用语音通讯程序来实现语音通讯。
REFUSE:接收到请求的命令字。
消息格式:REFUSE/客户端主机地址/用户名  使用说明:如果客户端收到该命令字,则表示对方已经拒绝了您的请求。这个请求是您发出的进行语音通话或者使用插件程序的请求。
    3.3 语音通讯的实现
  针对系统要求分别使用Delphi和VC开发了2个05独立的语音通讯模块。现在介绍使用Delphi6.0开发的语音通讯模块。
  语音采集与压缩使用Windows提供的ACM(Audio Compression Manager,音频压缩管理器)函数,ACM的声明文件提供并只提供直接调用ACMAPI的功能。如果有必要直接使用低层功能,可以按照下面的步骤使用ACM API。
    (1)制定输入输出格式
  为了实现语音的网络传输必须合理定义语音压缩的各种参数,只有正确地定义了语音压缩的各种参数,才能使语音在网络中快速传播,而不产生延迟,同时又能获得清晰的音质。
  可以使用waveFormatEX数据结构记录声音格式,这一数据结构在Delphi里是TwaveFormatEX,定义在MMSystem单元里。打开ACM流,可以通过调用acmStreamOpen函数实现,格式请参考MSDNplatform SDK的内容。制定输入输出缓冲区的大小,可以调用acmStreamSize,使用acmStreamOpen函数返回的流句柄作为参数。生成的转换头得到ACM源缓冲区和目的缓冲区的地址。ACM不会自动分配内存,必须由应用程序申请内存。
    (2)转换数据
  通过调用acmStream Converth函数实现。 acmStreamConvert函数包括流句柄和转换头句柄。这个函数通过设定转换头中的cbDstLength Used表明转换过程中真正被使用的字节数。
  (3)完成输出以后,释放资源。转换头用acm Stream Unperrepare Header函数来释放,流用acmStreamclose来关闭。
  经过比较采用ACM控件实现语音的采集、压缩、播放。这一组ACM控件包括3个Component:
ACMDialog,ACMWaveIn和ACMWaveOut。

  tmpformat.wBitsPerSample:=16;
                       //定义采样位数为16
  为了实现语音的采集,使用了控件TACMWaveIn,先为他开辟了一块连续的缓冲区,用控件TACMWaveIn的TACMWaveIn.Open事件来实现语音的采集。为了实现语音的播放,首先通过语句ACMWaveOut1.Open(@format);把采集到的经过压缩后的语音取出来。然后以流的方式,通过局域网传送到另一个主机的缓冲区。最后,通过语句ACMWaveOut1.PlayBack(pdata,Adata.Size)进行播放。
  网络传输可以使用各种方法实现,不同的方法需要不同的处理技巧。本系统使用INDY网络控件中的TIDUdpServer和TIDUdpClient这2个网络控件实现,基本符合要求。

4 结 语
  作者设计开发的这个IP电话系统,经过初步测试可以满足局域网用户正常的通话需求。由于时间的关系,系统的测试时间不是很长,仍然存在一定的缺陷。但在开发的过程中,各部分功能划分比较明确,所以对问题出现的原因比较容易定位。
  此外,同时开发出利用ASP语言编写的网页帐号申请系统,他可以在Web服务的支持下实现通过网页申请帐号的功能。出于用户需求扩充的考虑,也特别制定了插件的开发标准。客户可以根据自身的需要而开发自己的插件,来实现系统功能的扩充。目前,局域网使用较为成熟,宽带网的技术不断发展,各种网络语音通信产品的技术开发变得容易,基于上述技术的产品将得到更广泛的应用。介绍和讨论网络语音技术可能会对这些产品的开发起到积极的作用。

阅读(836) | 评论(0) | 转发(0) |
0

上一篇:JDK开发工具包

下一篇:追MM与设计模式

给主人留下些什么吧!~~