基于linux的实时语音通信软件设计与开发_第1页
基于linux的实时语音通信软件设计与开发_第2页
基于linux的实时语音通信软件设计与开发_第3页
基于linux的实时语音通信软件设计与开发_第4页
基于linux的实时语音通信软件设计与开发_第5页
已阅读5页,还剩53页未读 继续免费阅读

下载本文档

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

文档简介

1、本科毕业设计(论文)题 目基于linux的实时语音通信软件的设计与开发学 院计算机软件学院专 业计算机科学与技术(软件工程方向)姓 名班 级学 号指导教师二五年六月杭 州 电 子 科 技 大 学毕业设计(论文)任务书学 院计算机学院专 业计算机科学与技术(软件工程方向)班 级学生姓名指导教师学 号一、题目基于Linux的实时语音通信软件的设计与开发二、内容和要求需要达到的技术指标:本系统的主要功能是实现局域网内的端到端的实时语音通信,下面是功能的详细描述:1. 能实现端到端的语音通信(即输入主机名,能够与对方连接上;这边说话,另一边能听到声音;同样另一边说话,这边也能听到声音)2. 语音通信时

2、,确保传输可靠,声音不要失真;3. 能将说话声以WAV格式录音下来;可以发送录制的或者其它音乐的WAV文件给对方;4. 在这边“请求聊天”时,若对方在一定的时间过后还没有回复“同意”或者“拒绝就会提示电话留言;对方回来时可以按动“电话留言”键,播放内容;5. 有多个电话留言时,能正确存储、播放;6. 根据功能,做出相应的图形界面。阅读文献:1. 李卓桓,瞿华等编著.Linux网络编程机械工业出版社2. 宋国伟编著.GTK2.0 编程范例,清华大学出版社3. OSS-跨平台的音频接口简介4. 肖文鹏 .Linux音频编程指南 EB/OL5. 郭永冲,冯泽森,吾守尔斯拉木. 基于Linux平台的语

3、音传输工具的设计与实现.Computer Engineering第29卷第6期Vol.29 No.6.6. Linux声音设备编程实例http:/www.china-7. 王永福,殷毅,周峰.Internet 语音传输的设计与实现.三、起止日期及进度安排起止日期:2005年1月23日 至2005年06月10日进度安排:序号时间内容11月23日到3月1日熟悉开发环境,开发工具;23月1日到3月20日学习linux下网络编程;学习声卡功能的调用函数;33月20日到4月15日软件能实现“录音”,“聊天”功能;44月15日到5月1日所设想的软件功能,在终端模式下能够实现;55月1日到5月10日学习GT

4、K图形编程;65月10日到5月20日实现图形界面;75月20日到6月10日完成毕业论文指导教师(签名)年月日四、教研室审查意见:教研室主任(签名)年月日学院批准人(签名)年月日 基于linux的实时语音通信软件的设计与开发【摘要】 现在语音通信的软件很多,不过大部分软件,虽然功能完善,但是相对独立,不利于集成到自己开发的软件里。而有时我们需要把语音通信这个功能集成到自己开发的软件里,为此,设计和开发了这个基于Linux的实时语音通信软件。本软件基于Linux的实时语音通信软件,能实现局域网里端到端的语音通信和文本聊天两大功能。设计和开发此软件主要涉及到音频编程,网络编程,多线程编程以及QT D

5、esigner界面开发等知识。语音通信部分的设计思想:先实现声音的录音和播放功能,接着完成文本的网络传输;然后将文本信息替换成语音信息,实现单工模式的实时语音通信;能实现单工模式后,再利用多线程编程,实现双工模式的实时语音通信;最后是界面的设计和实现。文本聊天部分的设计思想:先完成一个客户端应用程序和一个服务器端应用程序。然后把服务器端核心代码嵌入到客户端程序里,完成文本聊天程序。实现单工模式语音通信后,如何把它整合成双工模式的实时语音通信是实现整个语音软件通信软件最难解决的问题。本论文所要研究阐述的是如何在Linux开发平台上,利用现有的音频编程和网络编程知识,设计和开发局域网里基于Linu

6、x的实时语音通信软件。【关键词】 实时 语音通信 QT LinuxDesign And Implementation of Real time Audio Communication Software Based on Linux【Abstract】 There are many audio communicatinon softwares now, but these softwares are relatively perfect and relatively independent , as a result , it is not easy to integrate these sof

7、twares into ourself developed software. Its the reason for designing and developing this real time audio communication software .This software real time audio communication software based on Linux ,can realize audio communication and text chatting two functions in LAN. Design and implementation of t

8、his real time audio communication software ranges over audio programming,network programming ,multithreading programming and QT Designer etc .The whole idea of designing audio communication is as follows: First finish recording audio and playing audio; After this ,try to transport text information o

9、ver network;Then achieve audio communication in simplex mode by replacing text information with audio information ;Then accomplish audio communication in duplex mode by bringing in multithreading programming ; Finally add an interface for this software .The whole idea of designing text chatting is a

10、s follows: First finish a client application and a server application ;Then embed the core code of server application into client application ,and finish this text chatting function .After realizing audio communication in simplex mode , how to realize audio communication in duplex mode is the most d

11、ifficult problem .This paper is written about how to design and develop this real time audio communication software base on Linux by making use of audio programming and network programming knowledge in Linux environment .【Keywords】 realtime audio communicate QT Linux目 录引 言1第一章 绪论21.1 语音传输现状21.2 Linu

12、x操作系统概述31.2.1 什么是Linux31.2.2 Linux的发展历史31.2.3 Linux下软件的安装和卸载4第二章 Linux音频编程52.1 数字音频52.2 编程接口62.2.1 open和close系统调用62.2.2 read和write系统调用62.2.3 ioctl系统调用72.3 音频设备文件72.3.1 设备文件 /dev/sndstat72.3.2 设备文件 /dev/dsp和/dev/audio72.3.3 设备文件 /dev/mixer82.4 音频编程框架9第三章 Linux下基于Socket的网络编程103.1 网络编程基础知识103.1.1 端口和套接

13、口103.1.2 套接字和套接口地址结构103.1.3 基本转换函数113.2 套接口操作函数123.2.1 socket()和bind()函数123.2.2 sendto()和recvfrom()函数123.2.3 listen()和accept()函数13第四章 语音通信的设计和实现144.1 语音通信功能简介144.2 整体设计方案144.3 设计方案的具体实现144.3.1 声音的录制和播放144.3.2 文本的网络传输164.3.3 单工模式的实时语音通信184.3.4 双工模式的实时语音通信194.4 用QT Designer实现界面214.4.1 Qt对象模型214.4.2 Qt

14、信号和槽214.4.3 终端模式存在的不足及改进224.4.4 Linux下多线程编程224.4.5 界面的具体实现23第五章 文本聊天265.1 文本聊天功能简介265.2 整体设计方案275.3 服务器端275.3.1 SimpleServer类275.3.2 ClientSocket类285.3.3 ServerInfo类295.4 客户端295.4.1 连接服务器295.4.2 发送文字305.5 文本聊天的实现30第六章 软件的运行效果及需改进的地方326.1 实时语音通信软件的运行效果326.2 实时语音通信软件需改进的地方33结 论34致 谢35参考文献36附录37引 言随着计算

15、机网络的日益普及,人们通过网络进行交流显得越来越重要。于是出现了一系列的通信软件。网络通讯软件,最早的是ICQ(国外)。随后中国腾讯公司制作出了自己的即时聊天软件OICQ,简称QQ。继而很多公司都看出了即时聊天软件中所蕴涵的巨大商机,于是其他各大门户网站相距推出了自己的软件,象SoHu的SQ,MSN的Msn,YaHoo的雅虎通等. 这些通信软件,虽然功能完善,但是相对独立,不利于集成到自己开发的软件里。而有时我们需要把语音通信这个功能集成到自己开发的软件里,为此,设计和开发了这个基于Linux的实时语音通信软件。本文所要研究阐述的是如何在Linux开发平台上,利用现有的音频编程和网络编程知识,

16、设计和开发局域网里基于Linux的实时语音通信软件。全文的思路如下:第一章将介绍语音传输现状以及该课题的开发平台,第二章介绍Linux音频编程,第三章介绍基于socket的网络编程,第四章给出实时语音通信软件中语音通信功能的设计方案以及实现过程,第五章讲实时语音通信软件中文本聊天功能的设计方案以及实现过程,第六章是描述软件的运行效果,指出需改进的地方。第一章 绪论1.1 语音传输现状当前随着计算机网络在性能和规模上的快速发展,网络服务及应用更加广泛、多样。除传统的数据业务以外,多媒体业务迅速增加,特别是在分组网上的语音传输技术迅速发展并广泛应用于实际生活,比如:VoIP得到了广泛应用,使它在产

17、生巨大的经济价值同时也对传统的电话产生了巨大的冲击。语音传输的关键技术:1. 实时传输协议当前多媒体传输软件多采用在UDP之上以RTP(Real-time Transport Protocol)协议为辅助协议的方式进行传输,RTP是IETF在1996年提出的适合实时数据传输的新型协议。它提供端到端的数据传输服务,包括负载标识、数据序列、时戳等。RTP提供具有实时特征的、端到端的数据传输业务,可以用来传送声音和视频。国际电信联盟在多媒体通信标准H.323中采用了RTP,它还可以被实时流协议(RTSP)所使用。由于RTP并不保证实时服务的QoS,因此RTP有一个姊妹协议:RTCP(Real-tim

18、e Transport Control Protocol) 协议。该协议使接收方和发送方交换控制信息去实现流控、QoS等要求。2. 多媒体同步在分组网上传输多媒体信息时,由于信源的分组从其产生、传输、到达处理要受到各种因素的影响,因而可能对分组的原有时间约束关系造成破坏,从而影响多媒体数据的播放。其中分组主要是由于网络传输而产生的延时及延时抖动, 比如不同的数据报的传输路径有可能不同、网络传输条件的变化。另外信源和信宿时钟偏差和现有的通用型操作系统不能够对实时应用提供充分的支持也都是影响同步很重要的因素。一个很常用的流内同步的办法是在接收端设立一个缓冲区,把延时抖动给滤除掉。在每一个有声期的开

19、始根据网络的延时情况进行缓冲调整。3. 丢包修复因为丢包严重地影响了语音质量,所以采取丢包修复方法是很有必要的。现在的实时传输中采用的丢包修复方法大体可以分为基于发送端和接收端结合的方法和单纯基于接收端的方法。前一类主要有以下几种方法:(1)重发法,它是用于修复TCP丢包的常用方法。虽然它不太符合实时要求,但在满足实时要求的条件下也可以作为实时传输的包修复方法。(2)交叠法(interleaving),它对分组实施一些处理从而降 低或分散了丢包的影响。它不增加额外的带宽要求,但却增加了延时。(3)冗余法,它把当前分组之前的某个分组采用 更低带宽要求的编码方式进行编码并由当前分组捎带发送。 这种

20、方法具有大致的修复能力,但它需要额外的带宽要求。 (4)异或法,它在发送端对连续多个数据包作异或运算求出 纠错包,而当发生丢包时丢失包由收到的数据包与纠错包作 异或运算而再生出来。它能够精确修复丢包,但却带来了延 时和额外的带宽要求。单纯基于接收端的错误消除法也有很 多种,比如用背景噪声、相邻分组替代丢失分组,也可以用 再生的方法进行修复。 4. 速率自适应由于网络的传输情况是时变的,我们设计的软件必须能够随着网络的变化而调整传输速率。这样做既是为减少拥塞,也是为了公平对待基于TCP的软件,因为基于TCP的 软件与基于UDP的多媒体软件共享带宽而且其具有拥塞控制 功能,假设我们设计的软件没有拥

21、塞控制功能,那么在网络 发生拥塞时,基于TCP的软件自动降低速率而我们的软件则 保持原来的速率,这样我们的多媒体软件则相当于从基于 TCP的软件那里偷取了带宽而且也加重了网络拥塞。1.2 Linux操作系统概述1.2.1 什么是Linux准确的说,是指Linux的kernel(系统的核心程序),其内核版权属于Linus Torvalds,在GPL(GNU General Public License)版权协议下发行, 任何人都可以自由的复制(copy), 修改(change), 套装分发(distribute),销售,但是不可以在分发时加入任何限制, 而且所有原码必须是公开的,所以任何人都可以

22、无偿取得所有执行文件和源代码。对于Linux用户和系统管理员来说,Linux是指包含Linux kernel、utilities (系统工具程序)以及application (应用软件)的一个完整的操作系统。Linux的应用软件是由自由软件基金会(FSF)开发的,全世界许多热心的程序员为Linux开发或移植了很多应用程序,包括X-Windows、Emacs、TCP/IP网络(包括SLIP/PPP/ISDN)等等,现在Linux(包括内核和大量的应用程序)光是执行程序就已经达到200M,完全安装后的规模将更大(大约500M左右)。 从本质上讲,Linux是Unix的”克隆”或Unix风格的操作系

23、统,在源代码级上兼容绝大部分的Unix标准(如IEEE POSIX),它遵从 POSIX规范,例如对于System V来说,把其上程序源代码拿到 Linux下重新编译后就可以运行。 Linux的标志是可爱的企鹅,至于为什么选用企鹅,Linus是这样说的:别的都被他人用了,企鹅,不是也非常可爱吗?!由Linux作者发布的仅仅是一个内核而己,有一些公司或组织把内核、原代码及相关的应用程序组织在一起发行, 于是就产生了不同的Linux发行(distributor)版本, 比较著名的发行版本有RedHat、SlackWare 、S.u.S.e、Debian 等。1.2.2 Linux的发展历史Linu

24、x的历史可以追溯到1990年,Linus Torvalds还是芬兰赫尔辛基大学的一名学生,用汇编语言写了一个在80386保护模式下处理多任务切换的程序。1991年10月5号发布了Linux 0.0.2版本,这个版本已经可以运行bash(一种用户与操作系统内核通讯的软件)和gcc(GNU C编译器)了。Linus从一开始,就决定自由扩散Linux、包括源代码,他把源代码发布在网上,随即就引起爱好者的注意,他们通过互连网也加入了Linux的内核开发工作,一大批高水平程序员的加入,使得Linux达到迅猛发展,到1993年底,Linux 1.0终于诞生。Linux 1.0已经是一个功能完备的操作系统了

25、,其内核写得紧凑高效,可以充分发挥硬件的性能,在4M内存的80386机器上也非常好。Linux加入GNU并遵循公共版权许可证(GPL),由于不排斥商家对自由软件进一步开发,不排斥在Linux上开发商业软件,故而使Linux又开始了一次飞跃,出现了很多的Linux发行版,如Slackware、Redhat、TurboLinux等十多种,而且还在增加,还有一些公司在Linux上开发商业软件或把其他Unix平台的软件移植到Linux上来,如今很多IT界的大腕如IBM、Intel、Oracle、Novell等都宣布支持Linux! 商家的加盟弥补了纯自由软件的不足和发展障碍,Linux得以迅速普及。1

26、.2.3 Linux下软件的安装和卸载三大软件安装和卸载方式:1.通过RPM软件包来安装RPM(REDHAT Package Management)标准的软件包,只需简单地输入命令“rpm -ivh xxx.rpm”即可。比如用户想安装OpenO-1.0.1.rpm软件包,只需输入命令“rpm -ivh OpenO-1.0.1.rpm”即可。RPM软件包发行方式的另一个优点是它能够方便地对已经安装的RPM软件包进行删除,只要使用“rpm -e OpenO-1.0.1”命令就能将刚才安装的OpenO-1.0.1.rpm从硬盘

27、上安全永久地删除。如果你是在X-Window环境中安装/删除软件,那便有更好的办法,如果使用的是KDE,可以使用KDE自带的Kpackage程序来对软件进行添加或删除,如果是使用GNOME,则可以使用Gnorpm程序对软件进行管理。这两个程序都很像微软Windows中的“添加/删除程序”功能。以RPM软件包发行方式的软件是最容易安装和管理的。2.Tar.gz(Tgz)软件包的安装 以Tar.gz为扩展名的软件包,是用Tar程序打包并用Gzip程序压缩的软件包。要安装这种软件包,需要先对软件包进行解压缩,使用“tar -zxfvfilename.tar.gz”可以对软件包进行解压缩,解压缩所得的

28、文件在以filename为名的目录中。进入该目录,可以看到解压缩出来的文件了。各种软件都有不同的安装方法,但是一般每个软件包解压缩后都有Install和Readme文件,帮助文件中会有详细的安装指导。以Tar.gz或Tgz包发行的软件有一个缺点,就是一般不带自动反安装程序,如果需要对已经安装的此类程序进行删除,就不得不仔细查看Makefile中的安装路径和文件名,这些对于初学者有一些难度。3.Tar.bz2软件包的安装以Tar.bz2为扩展名的软件包,是用Tar程序打包并用Bzip2程序进行压缩的软件包。它的优点是压缩率非常高,需要使用“bunzip2 filename.tar.bz2”进行解

29、压。但以该种方式发行的软件包与Tar.gz软件包有着同样的缺点,那就是删除非常麻烦。第二章 Linux音频编程2.1 数字音频音频信号是一种连续变化的模拟信号,但计算机只能处理和记录二进制的数字信号,由自然音源得到的音频信号必须经过一定的变换,成为数字音频信号之后,才能送到计算机中作进一步的处理。数字音频系统通过将声波的波型转换成一系列二进制数据,来实现对原始声音的重现,实现这一步骤的设备常被称为模/数转换器(A/D)。A/D转换器以每秒钟上万次的速率对声波进行采样,每个采样点都记录下了原始模拟声波在某一时刻的状态,通常称之为样本(sample),而每一秒钟所采样的数目则称为采样频率,通过将一

30、串连续的样本连接起来,就可以在计算机中描述一段声音了。对于采样过程中的每一个样本来说,数字音频系统会分配一定存储位来记录声波的振幅,一般称之为采样分辩率或者采样精度,采样精度越高,声音还原时就会越细腻。数字音频涉及到的概念非常多,对于在Linux下进行音频编程的程序员来说,最重要的是理解声音数字化的两个关键步骤:采样和量化。采样就是每隔一定时间就读一次声音信号的幅度,而量化则是将采样得到的声音信号幅度转换为数字值,从本质上讲,采样是时间上的数字化,而量化则是幅度上的数字化。下面介绍几个在进行音频编程时经常需要用到的技术指标:1.采样频率采样频率是指将模拟声音波形进行数字化时,每秒钟抽取声波幅度

31、样本的次数。采样频率的选择应该遵循奈奎斯特(Harry Nyquist)采样理论:如果对某一模拟信号进行采样,则采样后可还原的最高信号频率只有采样频率的一半,或者说只要采样频率高于输入信号最高频率的两倍,就能从采样信号系列重构原始信号。正常人听觉的频率范围大约在20Hz20kHz之间,根据奈奎斯特采样理论,为了保证声音不失真,采样频率应该在40kHz左右。常用的音频采样频率有8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz等,如果采用更高的采样频率,还可以达到DVD的音质。2.量化位数量化位数是对模拟音频信号的幅度进行数字化,它决定了模拟信

32、号数字化以后的动态范围,常用的有8位、12位和16位。量化位越高,信号的动态范围越大,数字化后的音频信号就越可能接近原始信号,但所需要的存贮空间也越大。3.声道数声道数是反映音频数字化质量的另一个重要因素,它有单声道和双声道之分。双声道又称为立体声,在硬件中有两条线路,音质和音色都要优于单声道,但数字化后占据的存储空间的大小要比单声道多一倍。出于对安全性方面的考虑,Linux下的应用程序无法直接对声卡这类硬件设备进行操作,而是必须通过内核提供的驱动程序才能完成。在Linux上进行音频编程的本质就是要借助于驱动程序,来完成对声卡的各种操作。目前Linux下常用的声卡驱动程序主要有两种:OSS和A

33、LSA。最早出现在Linux上的音频编程接口是OSS(Open Sound System),它由一套完整的内核驱动程序模块组成,可以为绝大多数声卡提供统一的编程接口。OSS出现的历史相对较长,这些内核模块中的一部分(OSS/Free)是与Linux内核源码共同免费发布的,另外一些则以二进制的形式由4Front Technologies公司提供。由于得到了商业公司的鼎力支持,OSS已经成为在Linux下进行音频编程的事实标准,支持OSS的应用程序能够在绝大多数声卡上工作良好。2.2 编程接口如何对各种音频设备进行操作是在Linux上进行音频编程的关键,通过内核提供的一组系统调用,应用程序能够访问

34、声卡驱动程序提供的各种音频设备接口,这是在Linux下进行音频编程最简单也是最直接的方法。无论是OSS还是ALSA,都是以内核驱动程序的形式运行在Linux内核空间中的,应用程序要想访问声卡这一硬件设备,必须借助于Linux内核所提供的系统调用(system call)。从程序员的角度来说,对声卡的操作在很大程度上等同于对磁盘文件的操作:首先使用open系统调用建立起与硬件间的联系,此时返回的文件描述符将作为随后操作的标识;接着使用read系统调用从设备接收数据,或者使用write系统调用向设备写入数据,而其它所有不符合读/写这一基本模式的操作都可以由ioctl系统调用来完成;最后,使用clo

35、se系统调用告诉Linux内核不会再对该设备做进一步的处理。2.2.1 open和close系统调用系统调用open可以获得对声卡的访问权,同时还能为随后的系统调用做好准备,其函数原型如下所示: int open(const char *pathname,int flags,int mode);参数pathname是将要被打开的设备文件的名称,对于声卡来讲一般是/dev/dsp(注:也可用/dev/audio)。参数flags用来指明应该以什么方式打开设备文件,它可以是O_RDONLY、O_WRONLY或者O_RDWR,分别表示以只读、只写或者读写的方式打开设备文件;参数mode通常是可选的,

36、它只有在指定的设备文件不存在时才会用到,指明新创建的文件应该具有怎样的权限。如果open系统调用能够成功完成,它将返回一个正整数作为文件标识符,在随后的系统调用中需要用到该标识符。如果open系统调用失败,它将返回-1,同时还会设置全局变量errno,指明是什么原因导致了错误的发生。当应用程序使用完声卡之后,需要用close系统调用将其关闭,以便及时释放占用的硬件资源,其函数原型如下所示:int close(int fd);参数fd是设备文件的标识符,它是在设备打开时获得的。一旦应用程序调用了close系统调用,Linux内核就会释放与之相关的各种资源,因此建议在不需要的时候尽量及时关闭已经打

37、开的设备。2.2.2 read和write系统调用系统调用read用来从声卡读取数据,其函数原型如下所示: int read(int fd, char *buf, size_t count);参数fd是设备文件的标识符,它是通过之前的open系统调用获得的;参数buf是指向缓冲区的字符指针,它用来保存从声卡获得的数据;参数count则用来限定从声卡获得的最大字节数。如果read系统调用成功完成,它将返回从声卡实际读取的字节数,通常情况会比count的值要小一些;如果read系统调用失败,它将返回-1,同时还会设置全局变量errno,来指明是什么原因导致了错误的发生。系统调用write用来向声卡

38、写入数据,其函数原型如下所示: size_t write(int fd, const char *buf, size_t count);系统调用write和系统调用read在很大程度是类似的,差别只在于write是向声卡写入数据,而read则是从声卡读入数据。参数fd同样是设备文件的标识符,它也是通过之前的open系统调用获得的;参数buf是指向缓冲区的字符指针,它保存着即将向声卡写入的数据;参数count则用来限定向声卡写入的最大字节数。如果write系统调用成功完成,它将返回向声卡实际写入的字节数;如果write系统调用失败,它将返回-1,同时还会设置全局变量errno,来指明是什么原因导

39、致了错误的发生。无论是read还是write,一旦调用之后Linux内核就会阻塞当前应用程序,直到数据成功地从声卡读出或者写入为止。2.2.3 ioctl系统调用系统调用ioctl可以对声卡进行控制,凡是对设备文件的操作不符合读/写基本模式的,都是通过ioctl来完成的,它可以影响设备的行为,或者返回设备的状态,其函数原型如下所示:int ioctl(int fd, int request, .);参数fd是设备文件的标识符,它是在设备打开时获得的;如果设备比较复杂,那么对它的控制请求相应地也会有很多种,参数request的目的就是用来区分不同的控制请求;通常说来,在对设备进行控制时还需要有其

40、它参数,这要根据不同的控制请求才能确定,并且可能是与硬件设备直接相关的。2.3 音频设备文件对于Linux应用程序员来讲,音频编程接口实际上就是一组音频设备文件,通过它们可以从声卡读取数据,或者向声卡写入数据,并且能够对声卡进行控制,设置采样频率和声道数目等等。2.3.1 设备文件 /dev/sndstat设备文件/dev/sndstat是声卡驱动程序提供的最简单的接口,通常它是一个只读文件,作用也仅仅只限于汇报声卡的当前状态。一般说来,/dev/sndstat是提供给最终用户来检测声卡的,不宜用于程序当中,因为所有的信息都可以通过ioctl系统调用来获得。 Linux提供的cat命令可以很方

41、便地从/dev/sndstat获得声卡的当前状态:cat /dev/sndstat.2.3.2 设备文件 /dev/dsp和/dev/audio声卡驱动程序提供的/dev/dsp是用于数字采样(sampling)和数字录音(recording)的设备文件,它对于Linux下的音频编程来讲非常重要:向该设备写数据即意味着激活声卡上的D/A转换器进行放音,而向该设备读数据则意味着激活声卡上的A/D转换器进行录音。目前许多声卡都提供有多个数字采样设备,它们在Linux下可以通过/dev/dsp1等设备文件进行访问。DSP是数字信号处理器(Digital Signal Processor)的简称,它是

42、用来进行数字信号处理的特殊芯片,声卡使用它来实现模拟信号和数字信号的转换。声卡中的DSP设备实际上包含两个组成部分:在以只读方式打开时,能够使用A/D转换器进行声音的输入;而在以只写方式打开时,则能够使用D/A转换器进行声音的输出。严格说来,Linux下的应用程序要么以只读方式打开/dev/dsp输入声音,要么以只写方式打开/dev/dsp输出声音,但事实上某些声卡驱动程序仍允许以读写的方式打开/dev/dsp,以便同时进行声音的输入和输出,这对于某些应用场合(如IP电话)来讲是非常关键的。在从DSP设备读取数据时,从声卡输入的模拟信号经过A/D转换器变成数字采样后的样本(sample),保存

43、在声卡驱动程序的内核缓冲区中,当应用程序通过read系统调用从声卡读取数据时,保存在内核缓冲区中的数字采样结果将被复制到应用程序所指定的用户缓冲区中。需要指出的是,声卡采样频率是由内核中的驱动程序所决定的,而不取决于应用程序从声卡读取数据的速度。如果应用程序读取数据的速度过慢,以致低于声卡的采样频率,那么多余的数据将会被丢弃;如果读取数据的速度过快,以致高于声卡的采样频率,那么声卡驱动程序将会阻塞那些请求数据的应用程序,直到新的数据到来为止。在向DSP设备写入数据时,数字信号会经过D/A转换器变成模拟信号,然后产生出声音。应用程序写入数据的速度同样应该与声卡的采样频率相匹配,否则过慢的话会产生

44、声音暂停或者停顿的现象,过快的话又会被内核中的声卡驱动程序阻塞,直到硬件有能力处理新的数据为止。与其它设备有所不同,声卡通常不会支持非阻塞(non-blocking)的I/O操作。无论是从声卡读取数据,或是向声卡写入数据,事实上都具有特定的格式(format),默认为8位无符号数据、单声道、8KHz采样率,如果默认值无法达到要求,可以通过ioctl系统调用来改变它们。通常说来,在应用程序中打开设备文件/dev/dsp之后,接下去就应该为其设置恰当的格式,然后才能从声卡读取或者写入数据。/dev/audio类似于/dev/dsp,它兼容于Sun工作站上的音频设备,使用的是mu-law编码方式。如

45、果声卡驱动程序提供了对/dev/audio的支持,那么在Linux上就可以通过cat命令,来播放在Sun工作站上用mu-law进行编码的音频文件:cat audio.au /dev/audio。对于应用程序来说,同一时刻只能使用/dev/audio或者/dev/dsp其中之一,因为它们是相同硬件的不同软件接口。2.3.3 设备文件 /dev/mixer在声卡的硬件电路中,混音器(mixer)是一个很重要的组成部分,它的作用是将多个信号组合或者叠加在一起,对于不同的声卡来说,其混音器的作用可能各不相同。运行在Linux内核中的声卡驱动程序一般都会提供/dev/mixer这一设备文件,它是应用程序

46、对混音器进行操作的软件接口。混音器电路通常由两个部分组成:输入混音器(input mixer)和输出混音器(output mixer)。输入混音器负责从多个不同的信号源接收模拟信号,这些信号源有时也被称为混音通道或者混音设备。模拟信号通过增益控制器和由软件控制的音量调节器后,在不同的混音通道中进行级别(level)调制,然后被送到输入混音器中进行声音的合成。混音器上的电子开关可以控制哪些通道中有信号与混音器相连,有些声卡只允许连接一个混音通道作为录音的音源,而有些声卡则允许对混音通道做任意的连接。经过输入混音器处理后的信号仍然为模拟信号,它们将被送到A/D转换器进行数字化处理。输出混音器的工作

47、原理与输入混音器类似,同样也有多个信号源与混音器相连,并且事先都经过了增益调节。当输出混音器对所有的模拟信号进行了混合之后,通常还会有一个总控增益调节器来控制输出声音的大小,此外还有一些音调控制器来调节输出声音的音调。经过输出混音器处理后的信号也是模拟信号,它们最终会被送给喇叭或者其它的模拟输出设备。对混音器的编程包括如何设置增益控制器的级别,以及怎样在不同的音源间进行切换,这些操作通常来讲是不连续的,而且不会像录音或者放音那样需要占用大量的计算机资源。由于混音器的操作不符合典型的读/写操作模式,因此除了open和close两个系统调用之外,大部分的操作都是通过ioctl系统调用来完成的。与/

48、dev/dsp不同,/dev/mixer允许多个应用程序同时访问,并且混音器的设置值会一直保持到对应的设备文件被关闭为止。为了简化应用程序的设计,Linux上的声卡驱动程序大多都支持将混音器的ioctl操作直接应用到声音设备上,也就是说如果已经打开了/dev/dsp,那么就不用再打开/dev/mixer来对混音器进行操作,而是可以直接用打开/dev/dsp时得到的文件标识符来设置混音器。2.4 音频编程框架对声卡进行编程时首先要做的是打开与之对应的硬件设备,这是借助于open系统调用来完成的,并且一般情况下使用的是/dev/dsp文件。采用何种模式对声卡进行操作也必须在打开设备时指定,对于不支

49、持全双工的声卡来说,应该使用只读或者只写的方式打开,只有那些支持全双工的声卡,才能以读写的方式打开,并且还要依赖于驱动程序的具体实现。Linux允许应用程序多次打开或者关闭与声卡对应的设备文件,从而能够很方便地在放音状态和录音状态之间进行切换,建议在进行音频编程时只要有可能就尽量使用只读或者只写的方式打开设备文件,因为这样不仅能够充分利用声卡的硬件资源,而且还有利于驱动程序的优化。第三章 Linux下基于Socket的网络编程3.1 网络编程基础知识3.1.1 端口和套接口若一台主机上同时有多个应用程序运行,他们都有可能使用TCP或UDP协议进行通信,则传输层协议收到数据后如何区分数据是传给哪

50、一个应用程序的呢?为此引用了端口和套接口。端口:标识传输层与应用程序的数据接口(服务访问点SAP),每个端口有一个16位的标识符,称为端口号。套接口:IP地址与端口号的组合,用来标识全网范围内的唯一一个端口,在TCP协议中用来标识一个连接。网络应用程序之间通过套接口来实现通信。常用的Socket类型有三种:流式套接口、数据报式套接口和原始套接口。流式是一种面向连接的Socket,针对于面向连接的TCP服务应用;数据报式Socket是一种无连接的Socket,对应于无连接的UDP服务应用;原始套接口是针对网络层编程用的套接口,例如ping命令的编写要用到原始套接口,因为ping的底层协议是ICM

51、P,而ICMP属于网络层。TCP/IP协议模型及各层所用协议如图3-1所示。应用层传输层网络层通信子网层http,telnet,ftp, Dns,rip,snmpTCPTCPIEEE802.3,FDDI,PPP,IP端口SAPSAPARP ,RARPICMP ,IGMP图3-1 TCP/IP协议模型及各层所用协议3.1.2 套接字和套接口地址结构套接字是套接口描述字的简称,是整型数字,它于文件描述符共用一段数值空间065535。应用程序中使用套接字来调用套接口,套接字可认为是指向套接口的指针,就像文件描述符是指向文件的指针一样。套接字和端口号是最容易混淆的两个概念,套接字不是人为指定的,而是由

52、Socket()的返回返回值决定的。一般来说,该套接字(文件描述符号)是系统当前可用的,并且是数值最小的整型描述符;端口号是客户应用程序中一般不认为指定, 而在服务器应用程序中必须指定,以为服务器应用程序要在某个固定端口上监听。Linux支持多种套接口地址结构,在这儿只介绍一下IPV4套接口地址结构和通用套接口地址结构。struct sockaddr unsigned short sa_family; /* 地址族, AF_XXX */char sa_data14; /* 14字节的协议地址 */;sa_family一般为AF_INET;sa_data则包含该socket的IP地址和端口号。I

53、PV4套接口地址结构struct sockaddr_in的定义如下:struct sockaddr_inshort int sin_family;/* 地址族 */unsigned short int sin_port; /* 端口号 */struct in_addr sin_addr; /* Internet地址 */unsigned char sin_zero8; /* 添0(和struct sockaddr一样大小*/;指向sockaddr_in 的指针和指向sockaddr的指针可以相互转换,这意味着如果一个函数所需参数类型是sockaddr时,你可以在函数调用的时候将一个指向sock

54、addr_in的指针转换为指向sickaddr的指针;或者相反。sin_family通常被赋值AF_INET;sin_port和sin_sddr应该转换成为网络字节优先顺序;struct in_addr其定义如下:struct in_addrunsigned long s_addr;如果你声明了一个ina作为一个struct sockaddr_in的结构,那么ina.sin_addr.s_addr就是4个字节的IP地址(按网络字节顺序排放)3.1.3 基本转换函数1. 网络字节顺序因为每一个机器内部对变量的字节存储顺序不同(有的系统是高位在前,地位在后,而有的系统是低位在前,高位在后),而网络

55、传输的数据是一定要统一顺序的。所以对与内部字节表示顺序和网络字节顺序不同的机器,一定要对数据进行转换(比如IP地址的表示,端口号的表示)。2. 有关的转换函数套接字字节转换程序的列表:htons() “Host to Network Short”主机字节顺序转换网络字节顺序(对无符号短型进行操作4 bytes)。htonl() “Host to Network Long” 主机字节顺序转换网络字节顺序(对无符号短型进行操作8 bytes)。ntohs() “Network to Host Short”网络字节顺序转换为主机字节顺序(对无符号短型进行操作4 bytes)。ntohl() “Net

56、work to Host Long” 网络字节顺序转换为主机字节顺序(对无符号长型进行操作8 bytes)。3. IP地址转换函数inet_addr(),它能够把一个用数字和点表示IP地址的字符串转换成一个无符号长整型。假设有一个struct sockaddr_in ina,并且IP是2,想把它存储到ina,可以使用inet_addr()。ina.sin_addr.s_addr = inet_addr(“2”);(注:inet_addr()返回的地方已经是网络字节顺序了)也可以把一个struct in_addr代表的IP地址打印出来(按照 数字.数字.数字.数字的格

温馨提示

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

评论

0/150

提交评论