版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、本科畢業(yè)設(shè)計(論文)題 目基于linux的實時語音通信軟件的設(shè)計與開發(fā)學(xué) 院計算機軟件學(xué)院專 業(yè)計算機科學(xué)與技術(shù)(軟件工程方向)姓 名班 級學(xué) 號指導(dǎo)教師二五年六月杭 州 電 子 科 技 大 學(xué)畢業(yè)設(shè)計(論文)任務(wù)書學(xué) 院計算機學(xué)院專 業(yè)計算機科學(xué)與技術(shù)(軟件工程方向)班 級011011學(xué)生姓名指導(dǎo)教師學(xué) 號一、題目基于linux的實時語音通信軟件的設(shè)計與開發(fā)二、內(nèi)容和要求需要達(dá)到的技術(shù)指標(biāo):本系統(tǒng)的主要功能是實現(xiàn)局域網(wǎng)內(nèi)的端到端的實時語音通信,下面是功能的詳細(xì)描述:1. 能實現(xiàn)端到端的語音通信(即輸入主機名,能夠與對方連接上;這邊說話,另一邊能聽到聲音;同樣另一邊說話,這邊也能聽到聲音)2.
2、 語音通信時,確保傳輸可靠,聲音不要失真;3. 能將說話聲以wav格式錄音下來;可以發(fā)送錄制的或者其它音樂的wav文件給對方;4. 在這邊“請求聊天”時,若對方在一定的時間過后還沒有回復(fù)“同意”或者“拒絕就會提示電話留言;對方回來時可以按動“電話留言”鍵,播放內(nèi)容;5. 有多個電話留言時,能正確存儲、播放;6. 根據(jù)功能,做出相應(yīng)的圖形界面。閱讀文獻(xiàn):1. 李卓桓,瞿華等編著.linux網(wǎng)絡(luò)編程機械工業(yè)出版社2. 宋國偉編著.gtk2.0 編程范例,清華大學(xué)出版社3. oss-跨平臺的音頻接口簡介4. 肖文鵬 .linux音頻編程指南 eb/ol5. 郭永沖,馮澤森,吾守爾斯拉木. 基于lin
3、ux平臺的語音傳輸工具的設(shè)計與實現(xiàn).computer engineering第29卷第6期vol.29 no.6.6. linux聲音設(shè)備編程實例http:/www.china-7. 王永福,殷毅,周峰.internet 語音傳輸?shù)脑O(shè)計與實現(xiàn).三、起止日期及進(jìn)度安排起止日期:2005年1月23日 至2005年06月10日進(jìn)度安排:序號時間內(nèi)容11月23日到3月1日熟悉開發(fā)環(huán)境,開發(fā)工具;23月1日到3月20日學(xué)習(xí)linux下網(wǎng)絡(luò)編程;學(xué)習(xí)聲卡功能的調(diào)用函數(shù);33月20日到4月15日軟件能實現(xiàn)“錄音”,“聊天”功能;44月15日到5月1日所設(shè)想的軟件功能,在終端模式下能夠?qū)崿F(xiàn);55月1日到5月1
4、0日學(xué)習(xí)gtk圖形編程;65月10日到5月20日實現(xiàn)圖形界面;75月20日到6月10日完成畢業(yè)論文指導(dǎo)教師(簽名)年月日四、教研室審查意見:教研室主任(簽名)年月日學(xué)院批準(zhǔn)人(簽名)年月日 基于linux的實時語音通信軟件的設(shè)計與開發(fā)【摘要】 現(xiàn)在語音通信的軟件很多,不過大部分軟件,雖然功能完善,但是相對獨立,不利于集成到自己開發(fā)的軟件里。而有時我們需要把語音通信這個功能集成到自己開發(fā)的軟件里,為此,設(shè)計和開發(fā)了這個基于linux的實時語音通信軟件。本軟件基于linux的實時語音通信軟件,能實現(xiàn)局域網(wǎng)里端到端的語音通信和文本聊天兩大功能。設(shè)計和開發(fā)此軟件主要涉及到音頻編程,網(wǎng)絡(luò)編程,多線程編程
5、以及qt designer界面開發(fā)等知識。語音通信部分的設(shè)計思想:先實現(xiàn)聲音的錄音和播放功能,接著完成文本的網(wǎng)絡(luò)傳輸;然后將文本信息替換成語音信息,實現(xiàn)單工模式的實時語音通信;能實現(xiàn)單工模式后,再利用多線程編程,實現(xiàn)雙工模式的實時語音通信;最后是界面的設(shè)計和實現(xiàn)。文本聊天部分的設(shè)計思想:先完成一個客戶端應(yīng)用程序和一個服務(wù)器端應(yīng)用程序。然后把服務(wù)器端核心代碼嵌入到客戶端程序里,完成文本聊天程序。實現(xiàn)單工模式語音通信后,如何把它整合成雙工模式的實時語音通信是實現(xiàn)整個語音軟件通信軟件最難解決的問題。本論文所要研究闡述的是如何在linux開發(fā)平臺上,利用現(xiàn)有的音頻編程和網(wǎng)絡(luò)編程知識,設(shè)計和開發(fā)局域網(wǎng)里
6、基于linux的實時語音通信軟件?!娟P(guān)鍵詞】 實時 語音通信 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 the
7、se softwares 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 implementatio
8、n of this 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 informa
9、tion over 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 chattin
10、g is as 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
11、most difficult 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 語音傳輸現(xiàn)狀21.
12、2 linux操作系統(tǒng)概述31.2.1 什么是linux31.2.2 linux的發(fā)展歷史31.2.3 linux下軟件的安裝和卸載4第二章 linux音頻編程52.1 數(shù)字音頻52.2 編程接口62.2.1 open和close系統(tǒng)調(diào)用62.2.2 read和write系統(tǒng)調(diào)用62.2.3 ioctl系統(tǒng)調(diào)用72.3 音頻設(shè)備文件72.3.1 設(shè)備文件 /dev/sndstat72.3.2 設(shè)備文件 /dev/dsp和/dev/audio72.3.3 設(shè)備文件 /dev/mixer82.4 音頻編程框架9第三章 linux下基于socket的網(wǎng)絡(luò)編程103.1 網(wǎng)絡(luò)編程基礎(chǔ)知識103.1.1
13、 端口和套接口103.1.2 套接字和套接口地址結(jié)構(gòu)103.1.3 基本轉(zhuǎn)換函數(shù)113.2 套接口操作函數(shù)123.2.1 socket()和bind()函數(shù)123.2.2 sendto()和recvfrom()函數(shù)123.2.3 listen()和accept()函數(shù)13第四章 語音通信的設(shè)計和實現(xiàn)144.1 語音通信功能簡介144.2 整體設(shè)計方案144.3 設(shè)計方案的具體實現(xiàn)144.3.1 聲音的錄制和播放144.3.2 文本的網(wǎng)絡(luò)傳輸164.3.3 單工模式的實時語音通信184.3.4 雙工模式的實時語音通信194.4 用qt designer實現(xiàn)界面214.4.1 qt對象模型214.
14、4.2 qt信號和槽214.4.3 終端模式存在的不足及改進(jìn)224.4.4 linux下多線程編程224.4.5 界面的具體實現(xiàn)23第五章 文本聊天265.1 文本聊天功能簡介265.2 整體設(shè)計方案275.3 服務(wù)器端275.3.1 simpleserver類275.3.2 clientsocket類285.3.3 serverinfo類295.4 客戶端295.4.1 連接服務(wù)器295.4.2 發(fā)送文字305.5 文本聊天的實現(xiàn)30第六章 軟件的運行效果及需改進(jìn)的地方326.1 實時語音通信軟件的運行效果326.2 實時語音通信軟件需改進(jìn)的地方33結(jié) 論34致 謝35參考文獻(xiàn)36附錄37引
15、 言隨著計算機網(wǎng)絡(luò)的日益普及,人們通過網(wǎng)絡(luò)進(jìn)行交流顯得越來越重要。于是出現(xiàn)了一系列的通信軟件。網(wǎng)絡(luò)通訊軟件,最早的是icq(國外)。隨后中國騰訊公司制作出了自己的即時聊天軟件oicq,簡稱qq。繼而很多公司都看出了即時聊天軟件中所蘊涵的巨大商機,于是其他各大門戶網(wǎng)站相距推出了自己的軟件,象sohu的sq,msn的msn,yahoo的雅虎通等. 這些通信軟件,雖然功能完善,但是相對獨立,不利于集成到自己開發(fā)的軟件里。而有時我們需要把語音通信這個功能集成到自己開發(fā)的軟件里,為此,設(shè)計和開發(fā)了這個基于linux的實時語音通信軟件。本文所要研究闡述的是如何在linux開發(fā)平臺上,利用現(xiàn)有的音頻編程和網(wǎng)
16、絡(luò)編程知識,設(shè)計和開發(fā)局域網(wǎng)里基于linux的實時語音通信軟件。全文的思路如下:第一章將介紹語音傳輸現(xiàn)狀以及該課題的開發(fā)平臺,第二章介紹linux音頻編程,第三章介紹基于socket的網(wǎng)絡(luò)編程,第四章給出實時語音通信軟件中語音通信功能的設(shè)計方案以及實現(xiàn)過程,第五章講實時語音通信軟件中文本聊天功能的設(shè)計方案以及實現(xiàn)過程,第六章是描述軟件的運行效果,指出需改進(jìn)的地方。第一章 緒論1.1 語音傳輸現(xiàn)狀當(dāng)前隨著計算機網(wǎng)絡(luò)在性能和規(guī)模上的快速發(fā)展,網(wǎng)絡(luò)服務(wù)及應(yīng)用更加廣泛、多樣。除傳統(tǒng)的數(shù)據(jù)業(yè)務(wù)以外,多媒體業(yè)務(wù)迅速增加,特別是在分組網(wǎng)上的語音傳輸技術(shù)迅速發(fā)展并廣泛應(yīng)用于實際生活,比如:voip得到了廣泛應(yīng)
17、用,使它在產(chǎn)生巨大的經(jīng)濟(jì)價值同時也對傳統(tǒng)的電話產(chǎn)生了巨大的沖擊。語音傳輸?shù)年P(guān)鍵技術(shù):1. 實時傳輸協(xié)議當(dāng)前多媒體傳輸軟件多采用在udp之上以rtp(real-time transport protocol)協(xié)議為輔助協(xié)議的方式進(jìn)行傳輸,rtp是ietf在1996年提出的適合實時數(shù)據(jù)傳輸?shù)男滦蛥f(xié)議。它提供端到端的數(shù)據(jù)傳輸服務(wù),包括負(fù)載標(biāo)識、數(shù)據(jù)序列、時戳等。rtp提供具有實時特征的、端到端的數(shù)據(jù)傳輸業(yè)務(wù),可以用來傳送聲音和視頻。國際電信聯(lián)盟在多媒體通信標(biāo)準(zhǔn)h.323中采用了rtp,它還可以被實時流協(xié)議(rtsp)所使用。由于rtp并不保證實時服務(wù)的qos,因此rtp有一個姊妹協(xié)議:rtcp(re
18、al-time transport control protocol) 協(xié)議。該協(xié)議使接收方和發(fā)送方交換控制信息去實現(xiàn)流控、qos等要求。2. 多媒體同步在分組網(wǎng)上傳輸多媒體信息時,由于信源的分組從其產(chǎn)生、傳輸、到達(dá)處理要受到各種因素的影響,因而可能對分組的原有時間約束關(guān)系造成破壞,從而影響多媒體數(shù)據(jù)的播放。其中分組主要是由于網(wǎng)絡(luò)傳輸而產(chǎn)生的延時及延時抖動, 比如不同的數(shù)據(jù)報的傳輸路徑有可能不同、網(wǎng)絡(luò)傳輸條件的變化。另外信源和信宿時鐘偏差和現(xiàn)有的通用型操作系統(tǒng)不能夠?qū)崟r應(yīng)用提供充分的支持也都是影響同步很重要的因素。一個很常用的流內(nèi)同步的辦法是在接收端設(shè)立一個緩沖區(qū),把延時抖動給濾除掉。在每一
19、個有聲期的開始根據(jù)網(wǎng)絡(luò)的延時情況進(jìn)行緩沖調(diào)整。3. 丟包修復(fù)因為丟包嚴(yán)重地影響了語音質(zhì)量,所以采取丟包修復(fù)方法是很有必要的?,F(xiàn)在的實時傳輸中采用的丟包修復(fù)方法大體可以分為基于發(fā)送端和接收端結(jié)合的方法和單純基于接收端的方法。前一類主要有以下幾種方法:(1)重發(fā)法,它是用于修復(fù)tcp丟包的常用方法。雖然它不太符合實時要求,但在滿足實時要求的條件下也可以作為實時傳輸?shù)陌迯?fù)方法。(2)交疊法(interleaving),它對分組實施一些處理從而降 低或分散了丟包的影響。它不增加額外的帶寬要求,但卻增加了延時。(3)冗余法,它把當(dāng)前分組之前的某個分組采用 更低帶寬要求的編碼方式進(jìn)行編碼并由當(dāng)前分組捎帶
20、發(fā)送。 這種方法具有大致的修復(fù)能力,但它需要額外的帶寬要求。 (4)異或法,它在發(fā)送端對連續(xù)多個數(shù)據(jù)包作異或運算求出 糾錯包,而當(dāng)發(fā)生丟包時丟失包由收到的數(shù)據(jù)包與糾錯包作 異或運算而再生出來。它能夠精確修復(fù)丟包,但卻帶來了延 時和額外的帶寬要求。單純基于接收端的錯誤消除法也有很 多種,比如用背景噪聲、相鄰分組替代丟失分組,也可以用 再生的方法進(jìn)行修復(fù)。 4. 速率自適應(yīng)由于網(wǎng)絡(luò)的傳輸情況是時變的,我們設(shè)計的軟件必須能夠隨著網(wǎng)絡(luò)的變化而調(diào)整傳輸速率。這樣做既是為減少擁塞,也是為了公平對待基于tcp的軟件,因為基于tcp的 軟件與基于udp的多媒體軟件共享帶寬而且其具有擁塞控制 功能,假設(shè)我們設(shè)計
21、的軟件沒有擁塞控制功能,那么在網(wǎng)絡(luò) 發(fā)生擁塞時,基于tcp的軟件自動降低速率而我們的軟件則 保持原來的速率,這樣我們的多媒體軟件則相當(dāng)于從基于 tcp的軟件那里偷取了帶寬而且也加重了網(wǎng)絡(luò)擁塞。1.2 linux操作系統(tǒng)概述1.2.1 什么是linux準(zhǔn)確的說,是指linux的kernel(系統(tǒng)的核心程序),其內(nèi)核版權(quán)屬于linus torvalds,在gpl(gnu general public license)版權(quán)協(xié)議下發(fā)行, 任何人都可以自由的復(fù)制(copy), 修改(change), 套裝分發(fā)(distribute),銷售,但是不可以在分發(fā)時加入任何限制, 而且所有原碼必須是公開的,所以
22、任何人都可以無償取得所有執(zhí)行文件和源代碼。對于linux用戶和系統(tǒng)管理員來說,linux是指包含linux kernel、utilities (系統(tǒng)工具程序)以及application (應(yīng)用軟件)的一個完整的操作系統(tǒng)。linux的應(yīng)用軟件是由自由軟件基金會(fsf)開發(fā)的,全世界許多熱心的程序員為linux開發(fā)或移植了很多應(yīng)用程序,包括x-windows、emacs、tcp/ip網(wǎng)絡(luò)(包括slip/ppp/isdn)等等,現(xiàn)在linux(包括內(nèi)核和大量的應(yīng)用程序)光是執(zhí)行程序就已經(jīng)達(dá)到200m,完全安裝后的規(guī)模將更大(大約500m左右)。 從本質(zhì)上講,linux是unix的”克隆”或unix
23、風(fēng)格的操作系統(tǒng),在源代碼級上兼容絕大部分的unix標(biāo)準(zhǔn)(如ieee posix),它遵從 posix規(guī)范,例如對于system v來說,把其上程序源代碼拿到 linux下重新編譯后就可以運行。 linux的標(biāo)志是可愛的企鵝,至于為什么選用企鵝,linus是這樣說的:別的都被他人用了,企鵝,不是也非??蓯蹎?!由linux作者發(fā)布的僅僅是一個內(nèi)核而己,有一些公司或組織把內(nèi)核、原代碼及相關(guān)的應(yīng)用程序組織在一起發(fā)行, 于是就產(chǎn)生了不同的linux發(fā)行(distributor)版本, 比較著名的發(fā)行版本有redhat、slackware 、s.u.s.e、debian 等。1.2.2 linux的發(fā)展
24、歷史linux的歷史可以追溯到1990年,linus torvalds還是芬蘭赫爾辛基大學(xué)的一名學(xué)生,用匯編語言寫了一個在80386保護(hù)模式下處理多任務(wù)切換的程序。1991年10月5號發(fā)布了linux 0.0.2版本,這個版本已經(jīng)可以運行bash(一種用戶與操作系統(tǒng)內(nèi)核通訊的軟件)和gcc(gnu c編譯器)了。linus從一開始,就決定自由擴(kuò)散linux、包括源代碼,他把源代碼發(fā)布在網(wǎng)上,隨即就引起愛好者的注意,他們通過互連網(wǎng)也加入了linux的內(nèi)核開發(fā)工作,一大批高水平程序員的加入,使得linux達(dá)到迅猛發(fā)展,到1993年底,linux 1.0終于誕生。linux 1.0已經(jīng)是一個功能完備
25、的操作系統(tǒng)了,其內(nèi)核寫得緊湊高效,可以充分發(fā)揮硬件的性能,在4m內(nèi)存的80386機器上也非常好。linux加入gnu并遵循公共版權(quán)許可證(gpl),由于不排斥商家對自由軟件進(jìn)一步開發(fā),不排斥在linux上開發(fā)商業(yè)軟件,故而使linux又開始了一次飛躍,出現(xiàn)了很多的linux發(fā)行版,如slackware、redhat、turbolinux等十多種,而且還在增加,還有一些公司在linux上開發(fā)商業(yè)軟件或把其他unix平臺的軟件移植到linux上來,如今很多it界的大腕如ibm、intel、oracle、novell等都宣布支持linux! 商家的加盟彌補了純自由軟件的不足和發(fā)展障礙,linux得以
26、迅速普及。1.2.3 linux下軟件的安裝和卸載三大軟件安裝和卸載方式:1.通過rpm軟件包來安裝rpm(redhat package management)標(biāo)準(zhǔn)的軟件包,只需簡單地輸入命令“rpm -ivh xxx.rpm”即可。比如用戶想安裝openo-1.0.1.rpm軟件包,只需輸入命令“rpm -ivh openo-1.0.1.rpm”即可。rpm軟件包發(fā)行方式的另一個優(yōu)點是它能夠方便地對已經(jīng)安裝的rpm軟件包進(jìn)行刪除,只要使用“rpm -e openo-1.0.1”命令就能將剛才安裝的openo-1.0.1.
27、rpm從硬盤上安全永久地刪除。如果你是在x-window環(huán)境中安裝/刪除軟件,那便有更好的辦法,如果使用的是kde,可以使用kde自帶的kpackage程序來對軟件進(jìn)行添加或刪除,如果是使用gnome,則可以使用gnorpm程序?qū)浖M(jìn)行管理。這兩個程序都很像微軟windows中的“添加/刪除程序”功能。以rpm軟件包發(fā)行方式的軟件是最容易安裝和管理的。2.tar.gz(tgz)軟件包的安裝 以tar.gz為擴(kuò)展名的軟件包,是用tar程序打包并用gzip程序壓縮的軟件包。要安裝這種軟件包,需要先對軟件包進(jìn)行解壓縮,使用“tar -zxfvfilename.tar.gz”可以對軟件包進(jìn)行解壓縮,
28、解壓縮所得的文件在以filename為名的目錄中。進(jìn)入該目錄,可以看到解壓縮出來的文件了。各種軟件都有不同的安裝方法,但是一般每個軟件包解壓縮后都有install和readme文件,幫助文件中會有詳細(xì)的安裝指導(dǎo)。以tar.gz或tgz包發(fā)行的軟件有一個缺點,就是一般不帶自動反安裝程序,如果需要對已經(jīng)安裝的此類程序進(jìn)行刪除,就不得不仔細(xì)查看makefile中的安裝路徑和文件名,這些對于初學(xué)者有一些難度。3.tar.bz2軟件包的安裝以tar.bz2為擴(kuò)展名的軟件包,是用tar程序打包并用bzip2程序進(jìn)行壓縮的軟件包。它的優(yōu)點是壓縮率非常高,需要使用“bunzip2 filename.tar.b
29、z2”進(jìn)行解壓。但以該種方式發(fā)行的軟件包與tar.gz軟件包有著同樣的缺點,那就是刪除非常麻煩。第二章 linux音頻編程2.1 數(shù)字音頻音頻信號是一種連續(xù)變化的模擬信號,但計算機只能處理和記錄二進(jìn)制的數(shù)字信號,由自然音源得到的音頻信號必須經(jīng)過一定的變換,成為數(shù)字音頻信號之后,才能送到計算機中作進(jìn)一步的處理。數(shù)字音頻系統(tǒng)通過將聲波的波型轉(zhuǎn)換成一系列二進(jìn)制數(shù)據(jù),來實現(xiàn)對原始聲音的重現(xiàn),實現(xiàn)這一步驟的設(shè)備常被稱為模/數(shù)轉(zhuǎn)換器(a/d)。a/d轉(zhuǎn)換器以每秒鐘上萬次的速率對聲波進(jìn)行采樣,每個采樣點都記錄下了原始模擬聲波在某一時刻的狀態(tài),通常稱之為樣本(sample),而每一秒鐘所采樣的數(shù)目則稱為采樣頻
30、率,通過將一串連續(xù)的樣本連接起來,就可以在計算機中描述一段聲音了。對于采樣過程中的每一個樣本來說,數(shù)字音頻系統(tǒng)會分配一定存儲位來記錄聲波的振幅,一般稱之為采樣分辯率或者采樣精度,采樣精度越高,聲音還原時就會越細(xì)膩。數(shù)字音頻涉及到的概念非常多,對于在linux下進(jìn)行音頻編程的程序員來說,最重要的是理解聲音數(shù)字化的兩個關(guān)鍵步驟:采樣和量化。采樣就是每隔一定時間就讀一次聲音信號的幅度,而量化則是將采樣得到的聲音信號幅度轉(zhuǎn)換為數(shù)字值,從本質(zhì)上講,采樣是時間上的數(shù)字化,而量化則是幅度上的數(shù)字化。下面介紹幾個在進(jìn)行音頻編程時經(jīng)常需要用到的技術(shù)指標(biāo):1.采樣頻率采樣頻率是指將模擬聲音波形進(jìn)行數(shù)字化時,每秒鐘
31、抽取聲波幅度樣本的次數(shù)。采樣頻率的選擇應(yīng)該遵循奈奎斯特(harry nyquist)采樣理論:如果對某一模擬信號進(jìn)行采樣,則采樣后可還原的最高信號頻率只有采樣頻率的一半,或者說只要采樣頻率高于輸入信號最高頻率的兩倍,就能從采樣信號系列重構(gòu)原始信號。正常人聽覺的頻率范圍大約在20hz20khz之間,根據(jù)奈奎斯特采樣理論,為了保證聲音不失真,采樣頻率應(yīng)該在40khz左右。常用的音頻采樣頻率有8khz、11.025khz、22.05khz、16khz、37.8khz、44.1khz、48khz等,如果采用更高的采樣頻率,還可以達(dá)到dvd的音質(zhì)。2.量化位數(shù)量化位數(shù)是對模擬音頻信號的幅度進(jìn)行數(shù)字化,它
32、決定了模擬信號數(shù)字化以后的動態(tài)范圍,常用的有8位、12位和16位。量化位越高,信號的動態(tài)范圍越大,數(shù)字化后的音頻信號就越可能接近原始信號,但所需要的存貯空間也越大。3.聲道數(shù)聲道數(shù)是反映音頻數(shù)字化質(zhì)量的另一個重要因素,它有單聲道和雙聲道之分。雙聲道又稱為立體聲,在硬件中有兩條線路,音質(zhì)和音色都要優(yōu)于單聲道,但數(shù)字化后占據(jù)的存儲空間的大小要比單聲道多一倍。出于對安全性方面的考慮,linux下的應(yīng)用程序無法直接對聲卡這類硬件設(shè)備進(jìn)行操作,而是必須通過內(nèi)核提供的驅(qū)動程序才能完成。在linux上進(jìn)行音頻編程的本質(zhì)就是要借助于驅(qū)動程序,來完成對聲卡的各種操作。目前l(fā)inux下常用的聲卡驅(qū)動程序主要有兩種
33、:oss和alsa。最早出現(xiàn)在linux上的音頻編程接口是oss(open sound system),它由一套完整的內(nèi)核驅(qū)動程序模塊組成,可以為絕大多數(shù)聲卡提供統(tǒng)一的編程接口。oss出現(xiàn)的歷史相對較長,這些內(nèi)核模塊中的一部分(oss/free)是與linux內(nèi)核源碼共同免費發(fā)布的,另外一些則以二進(jìn)制的形式由4front technologies公司提供。由于得到了商業(yè)公司的鼎力支持,oss已經(jīng)成為在linux下進(jìn)行音頻編程的事實標(biāo)準(zhǔn),支持oss的應(yīng)用程序能夠在絕大多數(shù)聲卡上工作良好。2.2 編程接口如何對各種音頻設(shè)備進(jìn)行操作是在linux上進(jìn)行音頻編程的關(guān)鍵,通過內(nèi)核提供的一組系統(tǒng)調(diào)用,應(yīng)用
34、程序能夠訪問聲卡驅(qū)動程序提供的各種音頻設(shè)備接口,這是在linux下進(jìn)行音頻編程最簡單也是最直接的方法。無論是oss還是alsa,都是以內(nèi)核驅(qū)動程序的形式運行在linux內(nèi)核空間中的,應(yīng)用程序要想訪問聲卡這一硬件設(shè)備,必須借助于linux內(nèi)核所提供的系統(tǒng)調(diào)用(system call)。從程序員的角度來說,對聲卡的操作在很大程度上等同于對磁盤文件的操作:首先使用open系統(tǒng)調(diào)用建立起與硬件間的聯(lián)系,此時返回的文件描述符將作為隨后操作的標(biāo)識;接著使用read系統(tǒng)調(diào)用從設(shè)備接收數(shù)據(jù),或者使用write系統(tǒng)調(diào)用向設(shè)備寫入數(shù)據(jù),而其它所有不符合讀/寫這一基本模式的操作都可以由ioctl系統(tǒng)調(diào)用來完成;最后
35、,使用close系統(tǒng)調(diào)用告訴linux內(nèi)核不會再對該設(shè)備做進(jìn)一步的處理。2.2.1 open和close系統(tǒng)調(diào)用系統(tǒng)調(diào)用open可以獲得對聲卡的訪問權(quán),同時還能為隨后的系統(tǒng)調(diào)用做好準(zhǔn)備,其函數(shù)原型如下所示: int open(const char *pathname,int flags,int mode);參數(shù)pathname是將要被打開的設(shè)備文件的名稱,對于聲卡來講一般是/dev/dsp(注:也可用/dev/audio)。參數(shù)flags用來指明應(yīng)該以什么方式打開設(shè)備文件,它可以是o_rdonly、o_wronly或者o_rdwr,分別表示以只讀、只寫或者讀寫的方式打開設(shè)備文件;參數(shù)mode通
36、常是可選的,它只有在指定的設(shè)備文件不存在時才會用到,指明新創(chuàng)建的文件應(yīng)該具有怎樣的權(quán)限。如果open系統(tǒng)調(diào)用能夠成功完成,它將返回一個正整數(shù)作為文件標(biāo)識符,在隨后的系統(tǒng)調(diào)用中需要用到該標(biāo)識符。如果open系統(tǒng)調(diào)用失敗,它將返回-1,同時還會設(shè)置全局變量errno,指明是什么原因?qū)е铝隋e誤的發(fā)生。當(dāng)應(yīng)用程序使用完聲卡之后,需要用close系統(tǒng)調(diào)用將其關(guān)閉,以便及時釋放占用的硬件資源,其函數(shù)原型如下所示:int close(int fd);參數(shù)fd是設(shè)備文件的標(biāo)識符,它是在設(shè)備打開時獲得的。一旦應(yīng)用程序調(diào)用了close系統(tǒng)調(diào)用,linux內(nèi)核就會釋放與之相關(guān)的各種資源,因此建議在不需要的時候盡量及
37、時關(guān)閉已經(jīng)打開的設(shè)備。2.2.2 read和write系統(tǒng)調(diào)用系統(tǒng)調(diào)用read用來從聲卡讀取數(shù)據(jù),其函數(shù)原型如下所示: int read(int fd, char *buf, size_t count);參數(shù)fd是設(shè)備文件的標(biāo)識符,它是通過之前的open系統(tǒng)調(diào)用獲得的;參數(shù)buf是指向緩沖區(qū)的字符指針,它用來保存從聲卡獲得的數(shù)據(jù);參數(shù)count則用來限定從聲卡獲得的最大字節(jié)數(shù)。如果read系統(tǒng)調(diào)用成功完成,它將返回從聲卡實際讀取的字節(jié)數(shù),通常情況會比count的值要小一些;如果read系統(tǒng)調(diào)用失敗,它將返回-1,同時還會設(shè)置全局變量errno,來指明是什么原因?qū)е铝隋e誤的發(fā)生。系統(tǒng)調(diào)用writ
38、e用來向聲卡寫入數(shù)據(jù),其函數(shù)原型如下所示: size_t write(int fd, const char *buf, size_t count);系統(tǒng)調(diào)用write和系統(tǒng)調(diào)用read在很大程度是類似的,差別只在于write是向聲卡寫入數(shù)據(jù),而read則是從聲卡讀入數(shù)據(jù)。參數(shù)fd同樣是設(shè)備文件的標(biāo)識符,它也是通過之前的open系統(tǒng)調(diào)用獲得的;參數(shù)buf是指向緩沖區(qū)的字符指針,它保存著即將向聲卡寫入的數(shù)據(jù);參數(shù)count則用來限定向聲卡寫入的最大字節(jié)數(shù)。如果write系統(tǒng)調(diào)用成功完成,它將返回向聲卡實際寫入的字節(jié)數(shù);如果write系統(tǒng)調(diào)用失敗,它將返回-1,同時還會設(shè)置全局變量errno,來指明
39、是什么原因?qū)е铝隋e誤的發(fā)生。無論是read還是write,一旦調(diào)用之后linux內(nèi)核就會阻塞當(dāng)前應(yīng)用程序,直到數(shù)據(jù)成功地從聲卡讀出或者寫入為止。2.2.3 ioctl系統(tǒng)調(diào)用系統(tǒng)調(diào)用ioctl可以對聲卡進(jìn)行控制,凡是對設(shè)備文件的操作不符合讀/寫基本模式的,都是通過ioctl來完成的,它可以影響設(shè)備的行為,或者返回設(shè)備的狀態(tài),其函數(shù)原型如下所示:int ioctl(int fd, int request, .);參數(shù)fd是設(shè)備文件的標(biāo)識符,它是在設(shè)備打開時獲得的;如果設(shè)備比較復(fù)雜,那么對它的控制請求相應(yīng)地也會有很多種,參數(shù)request的目的就是用來區(qū)分不同的控制請求;通常說來,在對設(shè)備進(jìn)行控制
40、時還需要有其它參數(shù),這要根據(jù)不同的控制請求才能確定,并且可能是與硬件設(shè)備直接相關(guān)的。2.3 音頻設(shè)備文件對于linux應(yīng)用程序員來講,音頻編程接口實際上就是一組音頻設(shè)備文件,通過它們可以從聲卡讀取數(shù)據(jù),或者向聲卡寫入數(shù)據(jù),并且能夠?qū)β暱ㄟM(jìn)行控制,設(shè)置采樣頻率和聲道數(shù)目等等。2.3.1 設(shè)備文件 /dev/sndstat設(shè)備文件/dev/sndstat是聲卡驅(qū)動程序提供的最簡單的接口,通常它是一個只讀文件,作用也僅僅只限于匯報聲卡的當(dāng)前狀態(tài)。一般說來,/dev/sndstat是提供給最終用戶來檢測聲卡的,不宜用于程序當(dāng)中,因為所有的信息都可以通過ioctl系統(tǒng)調(diào)用來獲得。 linux提供的cat
41、命令可以很方便地從/dev/sndstat獲得聲卡的當(dāng)前狀態(tài):cat /dev/sndstat.2.3.2 設(shè)備文件 /dev/dsp和/dev/audio聲卡驅(qū)動程序提供的/dev/dsp是用于數(shù)字采樣(sampling)和數(shù)字錄音(recording)的設(shè)備文件,它對于linux下的音頻編程來講非常重要:向該設(shè)備寫數(shù)據(jù)即意味著激活聲卡上的d/a轉(zhuǎn)換器進(jìn)行放音,而向該設(shè)備讀數(shù)據(jù)則意味著激活聲卡上的a/d轉(zhuǎn)換器進(jìn)行錄音。目前許多聲卡都提供有多個數(shù)字采樣設(shè)備,它們在linux下可以通過/dev/dsp1等設(shè)備文件進(jìn)行訪問。dsp是數(shù)字信號處理器(digital signal processor)
42、的簡稱,它是用來進(jìn)行數(shù)字信號處理的特殊芯片,聲卡使用它來實現(xiàn)模擬信號和數(shù)字信號的轉(zhuǎn)換。聲卡中的dsp設(shè)備實際上包含兩個組成部分:在以只讀方式打開時,能夠使用a/d轉(zhuǎn)換器進(jìn)行聲音的輸入;而在以只寫方式打開時,則能夠使用d/a轉(zhuǎn)換器進(jìn)行聲音的輸出。嚴(yán)格說來,linux下的應(yīng)用程序要么以只讀方式打開/dev/dsp輸入聲音,要么以只寫方式打開/dev/dsp輸出聲音,但事實上某些聲卡驅(qū)動程序仍允許以讀寫的方式打開/dev/dsp,以便同時進(jìn)行聲音的輸入和輸出,這對于某些應(yīng)用場合(如ip電話)來講是非常關(guān)鍵的。在從dsp設(shè)備讀取數(shù)據(jù)時,從聲卡輸入的模擬信號經(jīng)過a/d轉(zhuǎn)換器變成數(shù)字采樣后的樣本(samp
43、le),保存在聲卡驅(qū)動程序的內(nèi)核緩沖區(qū)中,當(dāng)應(yīng)用程序通過read系統(tǒng)調(diào)用從聲卡讀取數(shù)據(jù)時,保存在內(nèi)核緩沖區(qū)中的數(shù)字采樣結(jié)果將被復(fù)制到應(yīng)用程序所指定的用戶緩沖區(qū)中。需要指出的是,聲卡采樣頻率是由內(nèi)核中的驅(qū)動程序所決定的,而不取決于應(yīng)用程序從聲卡讀取數(shù)據(jù)的速度。如果應(yīng)用程序讀取數(shù)據(jù)的速度過慢,以致低于聲卡的采樣頻率,那么多余的數(shù)據(jù)將會被丟棄;如果讀取數(shù)據(jù)的速度過快,以致高于聲卡的采樣頻率,那么聲卡驅(qū)動程序?qū)枞切┱埱髷?shù)據(jù)的應(yīng)用程序,直到新的數(shù)據(jù)到來為止。在向dsp設(shè)備寫入數(shù)據(jù)時,數(shù)字信號會經(jīng)過d/a轉(zhuǎn)換器變成模擬信號,然后產(chǎn)生出聲音。應(yīng)用程序?qū)懭霐?shù)據(jù)的速度同樣應(yīng)該與聲卡的采樣頻率相匹配,否則過
44、慢的話會產(chǎn)生聲音暫?;蛘咄nD的現(xiàn)象,過快的話又會被內(nèi)核中的聲卡驅(qū)動程序阻塞,直到硬件有能力處理新的數(shù)據(jù)為止。與其它設(shè)備有所不同,聲卡通常不會支持非阻塞(non-blocking)的i/o操作。無論是從聲卡讀取數(shù)據(jù),或是向聲卡寫入數(shù)據(jù),事實上都具有特定的格式(format),默認(rèn)為8位無符號數(shù)據(jù)、單聲道、8khz采樣率,如果默認(rèn)值無法達(dá)到要求,可以通過ioctl系統(tǒng)調(diào)用來改變它們。通常說來,在應(yīng)用程序中打開設(shè)備文件/dev/dsp之后,接下去就應(yīng)該為其設(shè)置恰當(dāng)?shù)母袷?,然后才能從聲卡讀取或者寫入數(shù)據(jù)。/dev/audio類似于/dev/dsp,它兼容于sun工作站上的音頻設(shè)備,使用的是mu-law
45、編碼方式。如果聲卡驅(qū)動程序提供了對/dev/audio的支持,那么在linux上就可以通過cat命令,來播放在sun工作站上用mu-law進(jìn)行編碼的音頻文件:cat audio.au /dev/audio。對于應(yīng)用程序來說,同一時刻只能使用/dev/audio或者/dev/dsp其中之一,因為它們是相同硬件的不同軟件接口。2.3.3 設(shè)備文件 /dev/mixer在聲卡的硬件電路中,混音器(mixer)是一個很重要的組成部分,它的作用是將多個信號組合或者疊加在一起,對于不同的聲卡來說,其混音器的作用可能各不相同。運行在linux內(nèi)核中的聲卡驅(qū)動程序一般都會提供/dev/mixer這一設(shè)備文件,
46、它是應(yīng)用程序?qū)煲羝鬟M(jìn)行操作的軟件接口?;煲羝麟娐吠ǔS蓛蓚€部分組成:輸入混音器(input mixer)和輸出混音器(output mixer)。輸入混音器負(fù)責(zé)從多個不同的信號源接收模擬信號,這些信號源有時也被稱為混音通道或者混音設(shè)備。模擬信號通過增益控制器和由軟件控制的音量調(diào)節(jié)器后,在不同的混音通道中進(jìn)行級別(level)調(diào)制,然后被送到輸入混音器中進(jìn)行聲音的合成?;煲羝魃系碾娮娱_關(guān)可以控制哪些通道中有信號與混音器相連,有些聲卡只允許連接一個混音通道作為錄音的音源,而有些聲卡則允許對混音通道做任意的連接。經(jīng)過輸入混音器處理后的信號仍然為模擬信號,它們將被送到a/d轉(zhuǎn)換器進(jìn)行數(shù)字化處理。輸出
47、混音器的工作原理與輸入混音器類似,同樣也有多個信號源與混音器相連,并且事先都經(jīng)過了增益調(diào)節(jié)。當(dāng)輸出混音器對所有的模擬信號進(jìn)行了混合之后,通常還會有一個總控增益調(diào)節(jié)器來控制輸出聲音的大小,此外還有一些音調(diào)控制器來調(diào)節(jié)輸出聲音的音調(diào)。經(jīng)過輸出混音器處理后的信號也是模擬信號,它們最終會被送給喇叭或者其它的模擬輸出設(shè)備。對混音器的編程包括如何設(shè)置增益控制器的級別,以及怎樣在不同的音源間進(jìn)行切換,這些操作通常來講是不連續(xù)的,而且不會像錄音或者放音那樣需要占用大量的計算機資源。由于混音器的操作不符合典型的讀/寫操作模式,因此除了open和close兩個系統(tǒng)調(diào)用之外,大部分的操作都是通過ioctl系統(tǒng)調(diào)用來
48、完成的。與/dev/dsp不同,/dev/mixer允許多個應(yīng)用程序同時訪問,并且混音器的設(shè)置值會一直保持到對應(yīng)的設(shè)備文件被關(guān)閉為止。為了簡化應(yīng)用程序的設(shè)計,linux上的聲卡驅(qū)動程序大多都支持將混音器的ioctl操作直接應(yīng)用到聲音設(shè)備上,也就是說如果已經(jīng)打開了/dev/dsp,那么就不用再打開/dev/mixer來對混音器進(jìn)行操作,而是可以直接用打開/dev/dsp時得到的文件標(biāo)識符來設(shè)置混音器。2.4 音頻編程框架對聲卡進(jìn)行編程時首先要做的是打開與之對應(yīng)的硬件設(shè)備,這是借助于open系統(tǒng)調(diào)用來完成的,并且一般情況下使用的是/dev/dsp文件。采用何種模式對聲卡進(jìn)行操作也必須在打開設(shè)備時指
49、定,對于不支持全雙工的聲卡來說,應(yīng)該使用只讀或者只寫的方式打開,只有那些支持全雙工的聲卡,才能以讀寫的方式打開,并且還要依賴于驅(qū)動程序的具體實現(xiàn)。linux允許應(yīng)用程序多次打開或者關(guān)閉與聲卡對應(yīng)的設(shè)備文件,從而能夠很方便地在放音狀態(tài)和錄音狀態(tài)之間進(jìn)行切換,建議在進(jìn)行音頻編程時只要有可能就盡量使用只讀或者只寫的方式打開設(shè)備文件,因為這樣不僅能夠充分利用聲卡的硬件資源,而且還有利于驅(qū)動程序的優(yōu)化。第三章 linux下基于socket的網(wǎng)絡(luò)編程3.1 網(wǎng)絡(luò)編程基礎(chǔ)知識3.1.1 端口和套接口若一臺主機上同時有多個應(yīng)用程序運行,他們都有可能使用tcp或udp協(xié)議進(jìn)行通信,則傳輸層協(xié)議收到數(shù)據(jù)后如何區(qū)分
50、數(shù)據(jù)是傳給哪一個應(yīng)用程序的呢?為此引用了端口和套接口。端口:標(biāo)識傳輸層與應(yīng)用程序的數(shù)據(jù)接口(服務(wù)訪問點sap),每個端口有一個16位的標(biāo)識符,稱為端口號。套接口:ip地址與端口號的組合,用來標(biāo)識全網(wǎng)范圍內(nèi)的唯一一個端口,在tcp協(xié)議中用來標(biāo)識一個連接。網(wǎng)絡(luò)應(yīng)用程序之間通過套接口來實現(xiàn)通信。常用的socket類型有三種:流式套接口、數(shù)據(jù)報式套接口和原始套接口。流式是一種面向連接的socket,針對于面向連接的tcp服務(wù)應(yīng)用;數(shù)據(jù)報式socket是一種無連接的socket,對應(yīng)于無連接的udp服務(wù)應(yīng)用;原始套接口是針對網(wǎng)絡(luò)層編程用的套接口,例如ping命令的編寫要用到原始套接口,因為ping的底層
51、協(xié)議是icmp,而icmp屬于網(wǎng)絡(luò)層。tcp/ip協(xié)議模型及各層所用協(xié)議如圖3-1所示。應(yīng)用層傳輸層網(wǎng)絡(luò)層通信子網(wǎng)層http,telnet,ftp, dns,rip,snmptcptcpieee802.3,fddi,ppp,ip端口sapsaparp ,rarpicmp ,igmp圖3-1 tcp/ip協(xié)議模型及各層所用協(xié)議3.1.2 套接字和套接口地址結(jié)構(gòu)套接字是套接口描述字的簡稱,是整型數(shù)字,它于文件描述符共用一段數(shù)值空間065535。應(yīng)用程序中使用套接字來調(diào)用套接口,套接字可認(rèn)為是指向套接口的指針,就像文件描述符是指向文件的指針一樣。套接字和端口號是最容易混淆的兩個概念,套接字不是人為指
52、定的,而是由socket()的返回返回值決定的。一般來說,該套接字(文件描述符號)是系統(tǒng)當(dāng)前可用的,并且是數(shù)值最小的整型描述符;端口號是客戶應(yīng)用程序中一般不認(rèn)為指定, 而在服務(wù)器應(yīng)用程序中必須指定,以為服務(wù)器應(yīng)用程序要在某個固定端口上監(jiān)聽。linux支持多種套接口地址結(jié)構(gòu),在這兒只介紹一下ipv4套接口地址結(jié)構(gòu)和通用套接口地址結(jié)構(gòu)。struct sockaddr unsigned short sa_family; /* 地址族, af_xxx */char sa_data14; /* 14字節(jié)的協(xié)議地址 */;sa_family一般為af_inet;sa_data則包含該socket的ip地址
53、和端口號。ipv4套接口地址結(jié)構(gòu)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的指針可以相互轉(zhuǎn)換,這意味著如果一個函數(shù)所需參數(shù)類型是sockaddr時,你可以在函數(shù)調(diào)用的時候?qū)⒁粋€
54、指向sockaddr_in的指針轉(zhuǎn)換為指向sickaddr的指針;或者相反。sin_family通常被賦值af_inet;sin_port和sin_sddr應(yīng)該轉(zhuǎn)換成為網(wǎng)絡(luò)字節(jié)優(yōu)先順序;struct in_addr其定義如下:struct in_addrunsigned long s_addr;如果你聲明了一個ina作為一個struct sockaddr_in的結(jié)構(gòu),那么ina.sin_addr.s_addr就是4個字節(jié)的ip地址(按網(wǎng)絡(luò)字節(jié)順序排放)3.1.3 基本轉(zhuǎn)換函數(shù)1. 網(wǎng)絡(luò)字節(jié)順序因為每一個機器內(nèi)部對變量的字節(jié)存儲順序不同(有的系統(tǒng)是高位在前,地位在后,而有的系統(tǒng)是低位在前,高位在
55、后),而網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)是一定要統(tǒng)一順序的。所以對與內(nèi)部字節(jié)表示順序和網(wǎng)絡(luò)字節(jié)順序不同的機器,一定要對數(shù)據(jù)進(jìn)行轉(zhuǎn)換(比如ip地址的表示,端口號的表示)。2. 有關(guān)的轉(zhuǎn)換函數(shù)套接字字節(jié)轉(zhuǎn)換程序的列表:htons() “host to network short”主機字節(jié)順序轉(zhuǎn)換網(wǎng)絡(luò)字節(jié)順序(對無符號短型進(jìn)行操作4 bytes)。htonl() “host to network long” 主機字節(jié)順序轉(zhuǎn)換網(wǎng)絡(luò)字節(jié)順序(對無符號短型進(jìn)行操作8 bytes)。ntohs() “network to host short”網(wǎng)絡(luò)字節(jié)順序轉(zhuǎn)換為主機字節(jié)順序(對無符號短型進(jìn)行操作4 bytes)。ntohl(
56、) “network to host long” 網(wǎng)絡(luò)字節(jié)順序轉(zhuǎn)換為主機字節(jié)順序(對無符號長型進(jìn)行操作8 bytes)。3. ip地址轉(zhuǎn)換函數(shù)inet_addr(),它能夠把一個用數(shù)字和點表示ip地址的字符串轉(zhuǎn)換成一個無符號長整型。假設(shè)有一個struct sockaddr_in ina,并且ip是2,想把它存儲到ina,可以使用inet_addr()。ina.sin_addr.s_addr = inet_addr(“2”);(注:inet_addr()返回的地方已經(jīng)是網(wǎng)絡(luò)字節(jié)順序了)也可以把一個struct in_addr代表的ip地址打印出來(按照 數(shù)字.數(shù)字.數(shù)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 沈陽理工大學(xué)《工廠供電》2021-2022學(xué)年期末試卷
- 固定總價合同規(guī)范要求
- 國藥器械銷售合同
- 合同保證金遺失聲明
- 合同法第三章42條
- 2024年興安客運從業(yè)資格證考試模板
- 2024融資合同股權(quán)股份轉(zhuǎn)讓協(xié)議
- 2024工傷勞動合同范文
- 2024小區(qū)綠化工程合同
- 英語閱讀記錄卡-20210813175455
- 廣東省深圳市2023-2024學(xué)年高一上學(xué)期語文期末考試試卷(含答案)
- 河北省保定市定州市2024-2025學(xué)年九年級上學(xué)期期中考試化學(xué)試卷
- 2024-2030年狂犬疫苗行業(yè)市場深度分析及發(fā)展策略研究報告
- 《基因指導(dǎo)蛋白質(zhì)的合成》(第 1課時)教學(xué)設(shè)計
- 2024-2030年果蔬行業(yè)市場發(fā)展現(xiàn)狀及競爭格局與投資戰(zhàn)略研究報告
- 2 0 2 4 年 7 月 國開??啤斗ɡ韺W(xué)》期末紙質(zhì)考試 試題及答案
- 大疆在線測評題答案
- 公共政策分析第一章
- 行業(yè)協(xié)會重大活動備案報告制度
- 北京市海淀區(qū)2024學(xué)年七年級上學(xué)期語文期中試卷【含參考答案】
- 2024年新人教版七年級上冊數(shù)學(xué)教學(xué)課件 5.2 解一元一次方程 第4課時 利用去分母解一元一次方程
評論
0/150
提交評論