2023年全國碩士研究生考試考研英語一試題真題(含答案詳解+作文范文)_第1頁
已閱讀1頁,還剩35頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、<p>  計(jì)算機(jī)科學(xué)與工程學(xué)院</p><p><b>  綜合設(shè)計(jì)報(bào)告</b></p><p>  設(shè)計(jì)名稱: 智能系統(tǒng)應(yīng)用綜合設(shè)計(jì) </p><p>  設(shè)計(jì)題目: 音頻網(wǎng)絡(luò)傳輸?shù)膶?shí)現(xiàn) </p><p>  學(xué)生學(xué)號:

2、 </p><p>  專業(yè)班級: </p><p>  學(xué)生姓名: </p><p>  學(xué)生成績: </p><p&

3、gt;  指導(dǎo)教師(職稱): </p><p>  課題工作時(shí)間: 2013. 1. 7 至 2013. 1. 18 </p><p><b>  目錄</b></p><p>  摘 要……………………………………………………………………………………II</p>

4、<p>  Abstract……………………………………………………………………………………II</p><p>  第一章 課題背景…………………………………………………………………….......1</p><p>  1.1 音頻傳輸背景…………………………………………………………………………1</p><p>  1.2 音頻處理簡介………

5、…………………………………………………………………1</p><p>  1.3 socket簡介……………………………………………………………………………..3</p><p>  第二章 設(shè)計(jì)簡介及設(shè)計(jì)方案論述……………………………………………………...4</p><p>  2.1 設(shè)計(jì)簡介………………………………………………………………………………4&l

6、t;/p><p>  2.2 設(shè)計(jì)方案………………………………………………………………………………4</p><p>  2.3 界面設(shè)計(jì)………………………………………………………………………………7</p><p>  第三章 詳細(xì)設(shè)計(jì)………………………………………………………………………..11</p><p>  3.1 音頻處理…………

7、…………………………………………………………………...11</p><p>  3.2 音頻在局域網(wǎng)中的傳輸……………………………………………………………...14</p><p>  第四章 設(shè)計(jì)結(jié)果及分析………………………………………………………………..23</p><p>  4.1 設(shè)計(jì)結(jié)果……………………………………………………………………………..

8、.23</p><p>  4.2 錯(cuò)誤分析……………………………………………………………………………...25</p><p>  總 結(jié)……………………………………………………………………………………27</p><p>  致 謝……………………………………………………………………………………28</p><p>  參考文獻(xiàn)…

9、………………………………………………………………………………..29</p><p><b>  摘 要</b></p><p>  計(jì)算機(jī)網(wǎng)絡(luò)的飛速發(fā)展,給傳統(tǒng)音頻傳輸領(lǐng)域帶米了極大的沖擊并且為基于網(wǎng)絡(luò)的視、音頻通信提供了可能,在很多的網(wǎng)絡(luò)通信中,都需要將某一發(fā)送端的話音實(shí)時(shí)的傳榆給接收端。VC下的Client/server體系為這些應(yīng)用需求提供了一個(gè)不錯(cuò)的解決方

10、案。實(shí)時(shí)語音組播系統(tǒng)可以分成發(fā)送端、接收端和網(wǎng)絡(luò)傳輸3個(gè)子系統(tǒng).在此從TCP/IP通信的原理,包括路由選擇、傳輸協(xié)議、編程實(shí)現(xiàn)等角度。給出了比較完善的解決方案,從而實(shí)現(xiàn)了在局域網(wǎng)內(nèi)語音信號的實(shí)時(shí)傳輸,有很好的參考意義和實(shí)用價(jià)值。</p><p>  關(guān)鍵詞 局域網(wǎng);實(shí)時(shí)語音;TCP/IP;組播;音頻捕捉</p><p><b>  Abstract</b></

11、p><p>  The development of computer networks had brought great impact on the traditional audio and provided a possibility for video and audio communication based on network.In the network communication,some voi

12、ce from sending termination should be transmitted to the receiving termination real—timely.Client and Server system under VC platform provided a good solution for the applications,which included three systems such as sen

13、ding termination,receiving termination and network transmission.According to t</p><p>  Keywords:LAN;real-time voice; TCP/IP ;multieast; voice catch</p><p><b>  第一章 課題背景</b></p&g

14、t;<p>  1.1 音頻傳輸背景</p><p>  計(jì)算機(jī)網(wǎng)絡(luò)的飛速發(fā)展,給傳統(tǒng)音頻傳輸領(lǐng)域帶米了極大的沖擊。鑒于傳統(tǒng)音頻傳輸中難以克服的諸如不便于管理、布線復(fù)雜、難于實(shí)現(xiàn)自動切換等等的缺點(diǎn),數(shù)字網(wǎng)絡(luò)易管理、敗控、強(qiáng)大的數(shù)據(jù)傳輸能力無疑為未來傳統(tǒng)音頻傳輸指明了方向。</p><p>  目前以太網(wǎng)是計(jì)算機(jī)局域網(wǎng)絡(luò)的主流技術(shù),其應(yīng)用已遍及各個(gè)方面,每幢智能大廈都具備連通互

15、連網(wǎng)物理層布線。與專業(yè)音頻數(shù)字網(wǎng)絡(luò)技術(shù)比較,以太網(wǎng)具有成熟的技術(shù)標(biāo)準(zhǔn),以及極高的性能價(jià)格比。應(yīng)用以太網(wǎng)構(gòu)成音頻數(shù)字網(wǎng)絡(luò),將具有快速、廉價(jià)和方便等諸多優(yōu)點(diǎn),是近幾年來各大專業(yè)音頻設(shè)備研發(fā)公司研究的熱點(diǎn)。</p><p>  音頻傳輸?shù)膶?shí)時(shí)性要求是基于以太網(wǎng)來構(gòu)筑傳輸系統(tǒng)首先必須考慮和解決的問題。同時(shí),這樣一個(gè)分布式系統(tǒng)內(nèi)部的時(shí)鐘同步十分關(guān)鍵,否則時(shí)序邏輯將可能發(fā)生意想不到的混亂。</p><p&

16、gt;  本綜合設(shè)計(jì)根據(jù)音頻傳輸網(wǎng)絡(luò)的要求,結(jié)合傳統(tǒng)以太網(wǎng)技術(shù),研究了以太網(wǎng)的控制實(shí)時(shí)調(diào)度、系統(tǒng)時(shí)鐘同步和系統(tǒng)設(shè)計(jì)等技術(shù)問題,分析了音頻傳輸網(wǎng)絡(luò)的協(xié)議設(shè)計(jì),提出了理想的基于以太網(wǎng)的音頻實(shí)時(shí)傳輸系統(tǒng)的解決方案。</p><p>  1.2 音頻處理簡介</p><p>  一、音頻媒體的數(shù)字化處理</p><p>  隨著計(jì)算機(jī)技術(shù)的發(fā)展,特別是海量存儲設(shè)備和大容量內(nèi)

17、存在PC機(jī)上的實(shí)現(xiàn),對音頻媒體進(jìn)行數(shù)字化處理便成為可能。數(shù)字化處理的核心是對音頻信息的采樣,通過對采集到的樣本進(jìn)行加工,達(dá)成各種效果,這是音頻媒體數(shù)字化處理的基本含義。</p><p>  二、音頻媒體的基本處理</p><p>  基本的音頻數(shù)字化處理包括以下幾種: </p><p>  不同采樣率、頻率、通道數(shù)之間的變換和轉(zhuǎn)換。其中變換只是簡單地將其視為另一種格

18、式,而轉(zhuǎn)換通過重采樣來進(jìn)行,其中還可以根據(jù)需要采用插值算法以補(bǔ)償失真。 </p><p>  針對音頻數(shù)據(jù)本身進(jìn)行的各種變換,如淡入、淡出、音量調(diào)節(jié)等。 </p><p>  通過數(shù)字濾波算法進(jìn)行的變換,如高通、低通濾波器。</p><p>  三、音頻媒體的三維化處理</p><p>  長期以來,計(jì)算機(jī)的研究者們一直低估了聲音對人類在信息

19、處理中的作用。當(dāng)虛擬技術(shù)不斷發(fā)展之時(shí),人們就不再滿足單調(diào)平面的聲音,而更催向于具有空間感的三維聲音效果。聽覺通道可以與視覺通道同時(shí)工作,所以聲音的三維化處理不僅可以表達(dá)出聲音的空間信息,而且與視覺信息的多通道的結(jié)合可以創(chuàng)造出極為逼真的虛擬空間,這在未來的多媒體系統(tǒng)中是極為重要的。這也是在媒體處理方面的重要措施。 </p><p>  人類感知聲源的位置的最基本的理論是雙工理論,這種理論基于兩種因素:兩耳間聲音的到

20、達(dá)時(shí)間差和兩耳間聲音的強(qiáng)度差。時(shí)間差是由于距離的原因造成,當(dāng)聲音從正面?zhèn)鱽?,距離相等,所以沒有時(shí)間差,但若偏右三度則到達(dá)右耳的時(shí)間就要比左耳約少三十微秒,而正是這三十微秒,使得我們辨別出了聲源的位置。強(qiáng)度差是由于信號的衰減造成,信號的衰減是因?yàn)榫嚯x而自然產(chǎn)生的,或是因?yàn)槿说念^部遮擋,使聲音衰減,產(chǎn)生了強(qiáng)度的差別,使得靠近聲源一側(cè)的耳朵聽到的聲音強(qiáng)度要大于另一耳。 </p><p>  基于雙工理論,同樣地,只要把

21、一個(gè)普通的雙聲道音頻在兩個(gè)聲道之間進(jìn)行相互混合,便可以使普通雙聲道聲音聽起來具有三維音場的效果。這涉及到以下有關(guān)音場的兩個(gè)概念:音場的寬度和深度。 </p><p>  音場的寬度利用時(shí)間差的原理完成,由于現(xiàn)在是對普通立體聲音頻進(jìn)行擴(kuò)展,所以音源的位置始終在音場的中間不變,這樣就簡化了我們的工作。要處理的就只有把兩個(gè)聲道的聲音進(jìn)行適當(dāng)?shù)难訒r(shí)和強(qiáng)度減弱后相互混合。由于這樣的擴(kuò)展是有局限性的,即延時(shí)不能太長,否則就會

22、變?yōu)榛匾簟?</p><p>  音場的深度利用強(qiáng)度差的原理完成,具體的表現(xiàn)形式是回聲.音場越深,則回音的延時(shí)就越長.所以在回音的設(shè)置中應(yīng)至少提供三個(gè)參數(shù):回音的衰減率、回音的深度和回音之間的延時(shí)。同時(shí),還應(yīng)該提供用于設(shè)置另一通道混進(jìn)來的聲音深度的多少的選項(xiàng)。</p><p>  1.3 socket簡介</p><p>  本次綜合設(shè)計(jì)運(yùn)用的網(wǎng)絡(luò)傳輸?shù)暮诵姆绞骄褪?/p>

23、socket。所謂socket通常也稱作"套接字",應(yīng)用程序通常通過"套接字"向網(wǎng)絡(luò)發(fā)出請求或者應(yīng)答網(wǎng)絡(luò)請求。以J2SDK-1.3為例,Socket和ServerSocket類庫位于java .net包中。ServerSocket用于服務(wù)器端,Socket是建立網(wǎng)絡(luò)連接時(shí)使用的。在連接成功時(shí),應(yīng)用程序兩端都會產(chǎn)生一個(gè)Socket實(shí)例,操作這個(gè)實(shí)例,完成所需的會話。對于一個(gè)網(wǎng)絡(luò)連接來說,套接字是平等

24、的,并沒有差別,不因?yàn)樵诜?wù)器端或在客戶端而產(chǎn)生不同級別。不管是Socket還是ServerSocket它們的工作都是通過SocketImpl類及其子類完成的。</p><p>  常用的Socket類型有兩種:流式Socket(SOCK_STREAM)和數(shù)據(jù)報(bào)式Socket(SOCK_DGRAM)。流式是一種面向連接的Socket,針對于面向連接的TCP服務(wù)應(yīng)用;數(shù)據(jù)報(bào)式Socket是一種無連接的Socket,

25、對應(yīng)于無連接的UDP服務(wù)應(yīng)用。Socket為了建立Socket,程序可以調(diào)用Socket函數(shù),該函數(shù)返回一個(gè)類似于文件描述符的句柄。socket函數(shù)原型為:int socket(int domain,int type,int protocol);domain指明所使用的協(xié)議族,通常為PF_INET,(其與addrinfo 里的 AF_INET在現(xiàn)在看來是相同的。只是歷史上人們曾構(gòu)想將AF(地址家族address family)與PF(p

26、rotocol family 協(xié)議家族)分開,但實(shí)際上這種區(qū)分并未真正推廣,所以現(xiàn)在AF_INET和PF_INET具有相同的意義。其中AF_INET是基于IPv4而PF_INET基于IPv6)表示互聯(lián)網(wǎng)協(xié)議族(TCP/IP協(xié)議族);type參數(shù)指定socket的類型:SOCK_STREAM 或SOCK_DGRAM,Socke</p><p>  第二章 設(shè)計(jì)簡介及設(shè)計(jì)方案論述</p><p&

27、gt;<b>  2.1 設(shè)計(jì)簡介</b></p><p>  要實(shí)現(xiàn)局域網(wǎng)音頻數(shù)據(jù)傳輸,必須要解決兩個(gè)間題:第一個(gè)問題是語音的錄制和播放,即將一個(gè)用戶所講的語音信號錄制下來,等待傳輸; 同時(shí)將從網(wǎng)絡(luò)上接收到其它用戶所發(fā)來的語音信息進(jìn)行還原,使本地用戶聽到聲音; 對于聲音信息的錄制和播放,在這里采用的是低層音頻函數(shù)主要是考慮到語音信息傳輸?shù)膶?shí)時(shí)性要求。如果采用的是媒休控制接口函數(shù)(MCI )

28、 ,在進(jìn)行錄制時(shí)首先將錄制的信息保存在計(jì)算機(jī)的硬盤文件上,而數(shù)據(jù)發(fā)送時(shí)則需要將文件從硬盤讀到緩沖區(qū)中,由此而導(dǎo)致數(shù)據(jù)在接收方有較大的延遲而低層音頻函數(shù),由于它提供了對計(jì)算機(jī)緩沖區(qū)的直接操作,使得錄制的音頻信息在緩沖區(qū)中就可以發(fā)送,不必先保存在文件中,這樣就可以保證接收方無延遲地接收到發(fā)送方所發(fā)送的數(shù)據(jù)(所謂的無延遲指接收方感覺不出聲音滯后)。因此只能選擇較為低層的音頻函數(shù),雖然這種方法編程較為復(fù)雜,但卻較好地保證了一說“與“聽”是同時(shí)進(jìn)

29、行的第幾個(gè)問題是數(shù)據(jù)在局域網(wǎng)內(nèi)的傳輸,這是個(gè)網(wǎng)絡(luò)數(shù)據(jù)傳輸?shù)膯栴}。實(shí)現(xiàn)網(wǎng)絡(luò)信息的互通,MFC 中提供了封裝的CAsyncSocket 類,可以方便地派生出符合要求的接收發(fā)送類。</p><p><b>  2.2 設(shè)計(jì)方案</b></p><p>  系統(tǒng)的應(yīng)用平臺是Windows操作系統(tǒng),使用的是Winsock2規(guī)范,系統(tǒng)的開發(fā)工具是Microsoft VisualC

30、++6.0。此次設(shè)計(jì)的軟件,對組播組的成員,分為Server和Client 2種。進(jìn)行通信之前,Server和Client都必須先加入一個(gè)組播組。除了服務(wù)器端和用戶端以外,對于音頻的處理也很重要。下面將設(shè)計(jì)方案分為三部分來進(jìn)行介紹。</p><p>  2.2.1 音頻處理方案</p><p>  在Windows系列操作系統(tǒng)中,Microsoft提供了強(qiáng)大的DirectX工具。其中的Di

31、rectSound技術(shù)可以實(shí)現(xiàn)對聲音的實(shí)時(shí)捕捉和播放。</p><p><b>  1播放功能概述</b></p><p>  DirectSound緩沖區(qū)對象表示一個(gè)包含聲音數(shù)據(jù)的緩沖區(qū),這些數(shù)據(jù)以PCM格式被存儲。該對象不僅可以用于開始、停止或暫停聲音的播放,還能夠設(shè)置聲音數(shù)據(jù)中諸如頻率和格式等屬性。</p><p><b>  

32、2音頻捕獲</b></p><p>  Directsoundcapture對象可以查詢音頻捕獲設(shè)備的性能,并為從輸入源捕獲音頻而創(chuàng)建緩沖區(qū),它還能夠捕獲壓縮格式的音頻。DirectsoundcaptureBuffer對象表示一個(gè)用于捕獲音頻的緩沖區(qū).它可以循環(huán)利用。</p><p><b>  3播放聲音的過程</b></p><p&

33、gt;  (1)鎖定(IdirectsoundBuffer::Lock)從緩沖區(qū)的一部分;</p><p>  (2)寫數(shù)據(jù):將捕捉到的聲音數(shù)據(jù)寫入將要發(fā)送的數(shù)據(jù)包中;</p><p>  (3)解鎖(1directSoundBuffer::Unlock):對(1)的鎖定部分進(jìn)行解鎖;</p><p>  (4)將聲音傳送給主緩沖區(qū),并從哪里輸出(IdirectSo

34、undBuffer::Play)。</p><p>  2.2.2 Server設(shè)計(jì)方案</p><p>  Server就是可以隨時(shí)發(fā)言,實(shí)時(shí)接聽,不受他人限制。對來自Client的發(fā)言申請作出響應(yīng),然后將該信息拷貝到發(fā)送緩沖區(qū)發(fā)送出去。圖2.1為Server端數(shù)據(jù)流程圖。</p><p>  圖2.1 Server端數(shù)據(jù)流程圖</p><p&

35、gt;  2.2.3 Client設(shè)計(jì)方案</p><p>  Client就是可以實(shí)時(shí)接聽,每次發(fā)言前必須發(fā)出申請信息。當(dāng)申請信息發(fā)送出去后,組播組內(nèi)的所有成員都可以收到。當(dāng)Server發(fā)送出對申請信息的響應(yīng)信息后,各個(gè)Client將根據(jù)自己的本地地址與信息中包含的地址信息做比較,如果發(fā)現(xiàn)申請信息中的地址信息與本機(jī)地址一致,則說明是自己的發(fā)言申請的響應(yīng),于是處理;如果信息中的地址信息與本機(jī)地址不一致,那么不處理

36、。圖2.2是Client端數(shù)據(jù)流程圖。</p><p>  圖2.2 Client端數(shù)據(jù)流程圖</p><p><b>  2.3 界面設(shè)計(jì)</b></p><p>  一個(gè)功能完備的語音聊天系統(tǒng)必須擁有友好的界面。由于本次設(shè)計(jì)的是一種隨機(jī)建立服務(wù)器的系統(tǒng),所以每一個(gè)用戶都有可能成為服務(wù)器端。所以在任何人使用這一款軟件的時(shí)候應(yīng)該能夠第一眼看見自

37、己的IP地址,并且可以設(shè)置端口號其作用相當(dāng)于一個(gè)密鑰。當(dāng)局域網(wǎng)中的另一個(gè)用戶同時(shí)知道你的IP地址和端口號,并且你已經(jīng)建立好一個(gè)服務(wù)器的情況下才能夠連接。界面上應(yīng)該同時(shí)擁有建立服務(wù)器和連接服務(wù)器的選項(xiàng),還要有開始語音通信的按鈕,以便不方便進(jìn)行語音聊天的時(shí)候可以關(guān)閉該功能。市面上所有的語音聊天工具都附帶有一個(gè)即時(shí)打字聊天的功能,我所設(shè)計(jì)的這款軟件也擁有這樣的功能,因?yàn)椴皇请S時(shí)都有客觀條件進(jìn)行語音通信的。那么界面還應(yīng)該有一個(gè)編輯框和一個(gè)對話框

38、。所以界面初步在MFC中設(shè)計(jì)如圖2.3所示。</p><p>  圖 2.3 語音平臺界面初步成型</p><p>  可以從圖2.3看出,右上方的本機(jī)IP信息,端口號信息清晰明了,一目了然。連接服務(wù)器,建立服務(wù)器按鈕平行分布。左邊的編輯框和對話框也很清晰,符合人們運(yùn)用聊天工具的習(xí)慣。</p><p>  界面很單調(diào)不夠友好怎么辦?想把界面的做的好看有修改主題和設(shè)置

39、壁紙兩種方法,這里我用的是嵌入壁紙這個(gè)方法。全部設(shè)置好之后運(yùn)行的最后如圖2.4所示。</p><p>  圖 2.4 比較友好的界面成型</p><p>  設(shè)置嵌入背景的具體步驟如下:</p><p>  1.載入一張圖片ID設(shè)置為IDB_BIT_CHUYIN.</p><p>  2.在CExample2_ChatRoomDlg.h中定義

40、一個(gè)public下的CBrush m_brBk。CBrush:類CBrush封裝了Windows圖形設(shè)備接口(GDI)中的畫刷,畫刷也就是采取什么方案填充圖形的背景的工具。</p><p>  3. 在初始化函數(shù)OnInitDialog()中加入:</p><p>  BOOL CExample2_ChatRoomDlg::OnInitDialog()</p><p&g

41、t;<b>  {</b></p><p>  CDialog::OnInitDialog();</p><p>  CBitmap bmp;</p><p>  bmp.LoadBitmap(IDB_BIT_CHUYIN);</p><p>  m_brBk.CreatePatternBrush(&bmp);&

42、lt;/p><p>  bmp.DeleteObject();</p><p>  return TRUE; </p><p><b>  }</b></p><p>  之所以在OnInitDialog()中進(jìn)行操作是因?yàn)椋篛nInitDialog ( ):用于對對話框類的變量的初始化(注意:是在產(chǎn)生對話框之前就初始化),

43、是WM_INITDIALOG消息產(chǎn)生的消息處理函數(shù),覆蓋該函數(shù)可改變對話框初始設(shè)置。</p><p>  4. 打開類向?qū)?找到WM_CTLCOLOR消息,重載得對應(yīng)函數(shù)OnCtlColor(),添加如下:</p><p>  HBRUSH CExample2_ChatRoomDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) <

44、;/p><p><b>  {</b></p><p>  HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);</p><p>  // TODO: Change any attributes of the DC here</p><p>  if (pWnd ==

45、 this)</p><p>  { return m_brBk; } </p><p>  // TODO: Return a different brush if the default is not desired</p><p>  return hbr;</p><p><b>  }</b></p>

46、;<p>  其中WM_CTLCOLOR消息的功能:WM_CTLCOLOR是一個(gè)由控制(Control)發(fā)送給它父窗口的通知消息(Notification message)。利用向?qū)в成湓撓a(chǎn)生函數(shù):HBRUSH CAboutDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);參數(shù)pDC是TestDlg的設(shè)備上下文,pWnd是TestDlg中發(fā)送該消息的contro

47、l指針,nCtlColor是Control的類型編碼。WM_CTLCOLOR是系統(tǒng)在繪制控件的時(shí)候自動發(fā)送的,如果需要自定義,就截取這個(gè)消息并重載它的響應(yīng)函數(shù),用classWizard添加WM_CTLCOLOR消息然后編輯其OnCtlColor函數(shù)。這樣Windows向應(yīng)用程序發(fā)送消息WM_CTLCOLOR,應(yīng)用程序處理WM_CTLCOLOR消息并返回一個(gè)用來繪畫窗體背景的刷子句柄。</p><p>  經(jīng)過了以

48、上4個(gè)步驟之后一個(gè)友好的語音聊天平臺界面的設(shè)計(jì)已經(jīng)很完備,用戶使用這款軟件會覺得很舒服。</p><p><b>  第三章 詳細(xì)設(shè)計(jì)</b></p><p><b>  3.1 音頻處理</b></p><p>  3.1.1 WAVEHDR簡介</p><p>  本次課程設(shè)計(jì)中對音頻信號的采

49、集,處理,回放都是基于Windows下低層波形音頻數(shù)據(jù)塊結(jié)構(gòu)WAVEHDR來實(shí)現(xiàn)的,因此有必要對這一數(shù)據(jù)結(jié)構(gòu)進(jìn)行說明,該數(shù)據(jù)結(jié)構(gòu)聲明如下:</p><p>  01.type struct{</p><p>  02.LPSTR lpData; //指向鎖定的數(shù)據(jù)緩沖區(qū)的指針</p><p>  03.DWORD dwBuf

50、ferLength; //數(shù)據(jù)緩沖區(qū)的大小</p><p>  04.DWORD dwByteRecorded; //錄音時(shí)指明緩沖區(qū)中的數(shù)據(jù)量</p><p>  05.DWORD dwUser; //用戶數(shù)據(jù)</p><p>  06.DWORD dwFlag; //提供緩沖區(qū)信息的標(biāo)

51、志</p><p>  07.DWORD dwLoops; //循環(huán)播放的次數(shù)</p><p>  08.struct wavehdr_tag * lpNext; //保留</p><p>  09.DWORD reserved; //保留</p><p>  10.} WAV

52、EHDR;</p><p>  聲音的采集和播放其實(shí)都是在操作這個(gè)音頻數(shù)據(jù)塊結(jié)構(gòu),實(shí)際上主要用到的就是第一個(gè)成員變量lpData, 所以我們只要在分配緩沖區(qū)(內(nèi)存)的同時(shí)相應(yīng)分配WAVEHDR數(shù)據(jù)塊結(jié)構(gòu),然后將緩沖區(qū)的指針賦給對應(yīng)的數(shù)據(jù)塊結(jié)構(gòu)的成員變量 lpData,這樣當(dāng)一個(gè)緩沖區(qū)填滿后,也就是一個(gè)音頻數(shù)據(jù)塊填滿了,通過消息機(jī)制就可以在消息函數(shù)中進(jìn)行處理和播放,播放完后又可通過消息函數(shù)把緩沖區(qū)再送給音頻設(shè)備輸入

53、驅(qū)動程序,繼續(xù)進(jìn)行采集并播放,當(dāng)你一次性分配多個(gè)緩沖區(qū)和數(shù)據(jù)塊結(jié)構(gòu)并賦給音頻設(shè)備輸入驅(qū)動程序后,至于把哪個(gè)緩沖區(qū)填滿,然后再把哪個(gè)空緩沖區(qū)賦給設(shè)備輸入驅(qū)動程序,不需人為干預(yù),完全由Windows控制,這就是一種用動態(tài)循環(huán)緩沖區(qū)實(shí)現(xiàn)話音的實(shí)時(shí)采集、播放的簡單而巧妙的辦法。</p><p>  3.1.2 初始化操作</p><p>  首先考慮到的是把從話筒中傳入的聲音轉(zhuǎn)化為數(shù)據(jù),然后再對其

54、進(jìn)行處理,即聲音的采集與處理。</p><p>  Windows多媒體擴(kuò)展提供2個(gè)層次的音頻服務(wù):</p><p>  (1)低層音頻服務(wù)允許應(yīng)用程序直接與音頻驅(qū)動程序通信,以管理聲音的播放和錄制。低層音頻服務(wù)要求較多的編程,但可以對播放提供更強(qiáng)的控制。</p><p>  (2)高層音頻服務(wù)只需少量編程就能播放和錄制音頻文件。與低層音頻服務(wù)相比,高層音頻服務(wù)容易

55、使用,需要編程較少。高層服務(wù)可以滿足</p><p>  應(yīng)用程序?qū)σ纛l的簡單要求。</p><p>  本次課程設(shè)計(jì)中使用的是低層音頻服務(wù)。低層音頻服務(wù)可以更加靈活的控制不同類型的音頻設(shè)備。對波形設(shè)備而言,不論是播放還是錄制波形,系統(tǒng)要處理的數(shù)據(jù)都很多,為了少占用內(nèi)存,低層音頻服務(wù)以數(shù)據(jù)塊為單位進(jìn)行管理。他要求應(yīng)用程序自己分配內(nèi)存,并將內(nèi)存塊的地址、大小等信息告訴低層音頻驅(qū)動程序,使其

56、為錄放音頻操作做好準(zhǔn)備。</p><p>  音頻播放時(shí),應(yīng)用程序?qū)⒁シ诺臄?shù)據(jù)填充到這個(gè)內(nèi)存塊中,然后通知驅(qū)動程序播放該塊。驅(qū)動程序播放數(shù)據(jù)在后臺進(jìn)行,應(yīng)用程序可以在前臺繼續(xù)自己的工作。當(dāng)一塊音頻播放完時(shí),應(yīng)用程序再向驅(qū)動程序提供新的數(shù)據(jù),如此反復(fù),直到音頻數(shù)據(jù)播放完畢。</p><p>  音頻錄制時(shí),應(yīng)用程序向驅(qū)動程序提供驅(qū)動程序錄制的緩沖區(qū)內(nèi)存塊,當(dāng)驅(qū)動程序錄制充滿了給定的緩沖區(qū)后

57、,會以某種方式通知應(yīng)用程序作一定的處理。驅(qū)動程序錄制數(shù)據(jù)在后臺進(jìn)行,應(yīng)用程序可以在前臺繼續(xù)自己的工作。</p><p>  要實(shí)現(xiàn)對音頻的采集與播放,必須經(jīng)過如下的初始化操作:</p><p> ?、儆脀aveInGetNumDevs()和waveOutGetNumDevs()查看當(dāng)前系統(tǒng)波形音頻輸入、輸出設(shè)備;</p><p> ?、诎?000Hz,16Bit,單

58、聲道,16K/S的格式設(shè)置WAVEFORMATEX結(jié)構(gòu)的成員變量,當(dāng)然也可以改為其他WAVE格式;</p><p> ?、塾脀aveInOpen(...) 和waveOutOpen(...)分別調(diào)用WAVE_FORMAT_QUERY參數(shù)查看波形輸入設(shè)備是否支持所設(shè)定的格式;</p><p> ?、茉俅握{(diào)用用waveInOpen(...) 和waveOutOpen(...)分別調(diào)用CALLB

59、ACK_WINDOW參數(shù)打開波形輸入設(shè)備;</p><p> ?、莘謩e給音頻數(shù)據(jù)塊和音頻數(shù)據(jù)緩沖區(qū)分配、鎖定全局內(nèi)存;</p><p> ?、蕹跏蓟纛l數(shù)據(jù)塊結(jié)構(gòu)各成員變量,主要是將每個(gè)緩沖區(qū)指針賦給對應(yīng)數(shù)據(jù)塊結(jié)構(gòu)中的緩沖區(qū)指針變量lpData;調(diào)用waveInPrepareHeader(...)和waveInAddBuffer(...)將音頻數(shù)據(jù)塊賦給輸入設(shè)備驅(qū)動程序;</p>

60、;<p> ?、哒{(diào)用waveInStart(...)函數(shù)開始錄音。</p><p>  經(jīng)過以上一系列初始化操作,就可以完成音頻的輸入與采集了。</p><p>  3.1.3 消息操作</p><p>  錄音開始后,每當(dāng)有采樣數(shù)據(jù)填滿數(shù)據(jù)塊后,設(shè)備驅(qū)動程序就會發(fā)消息MM_WIM_DATA給用戶窗口,本設(shè)計(jì)中相應(yīng)的消息回調(diào)函數(shù)是WriteBuffer

61、Full(),代碼如下所示:</p><p>  void CExample2_ChatRoomDlg::WriteBufferFull(LPARAM lp,WPARAM wp)</p><p><b>  {</b></p><p>  m_sound.Play();</p><p>  CSingleLock loc

62、k(&m_mutex,TRUE);</p><p>  CMessg msg;</p><p>  msg.m_strText="";</p><p>  msg.m_tag=1;</p><p>  memcpy(msg.m_buffer,m_sound.m_cBufferIn,MAX_BUFFER_SIZE);

63、</p><p>  if(!m_bClient)</p><p><b>  {</b></p><p>  POSITION pos;</p><p>  for(pos=m_connectionList.GetHeadPosition();pos!=NULL;)</p><p><b&

64、gt;  {</b></p><p>  CClientSocket * t= (CClientSocket*)m_connectionList.GetNext(pos);</p><p>  t->SendMessage(&msg);</p><p><b>  }</b></p><p>&

65、lt;b>  }</b></p><p><b>  else</b></p><p><b>  {</b></p><p>  m_clientsocket.SendMessage(&msg);</p><p><b>  }</b></p&

66、gt;<p>  m_sound.FreeRecordBuffer();</p><p>  m_sound.FreePlayBuffer();</p><p>  lock.Unlock();//</p><p><b>  }</b></p><p>  該函數(shù)的功能是首先調(diào)用自己編寫的sound類的P

67、lay()函數(shù)對采集的音頻進(jìn)行播放。Play()函數(shù)中只有一條如下語句:</p><p>  memcpy(m_cBufferOut,m_cBufferIn,MAX_BUFFER_SIZE);</p><p>  可以看出,該函數(shù)實(shí)際上就是輸入的音頻數(shù)據(jù)拷貝到輸出的數(shù)據(jù)數(shù)組中,因?yàn)橐呀?jīng)經(jīng)過了前面所述的初始化過程,這行代碼就可以實(shí)現(xiàn)對音頻輸入數(shù)據(jù)的回放。</p><p&g

68、t;  之后WriteBufferFull()函數(shù)又將采集到的數(shù)據(jù)通過服務(wù)器發(fā)送給客戶端,或是通過客戶端發(fā)送給服務(wù)器。這要根據(jù)運(yùn)行的進(jìn)程是服務(wù)器端進(jìn)程還是客戶端進(jìn)程而定。這樣,每當(dāng)有音頻輸入后,一旦數(shù)據(jù)塊被填滿,就能通過消息響應(yīng)函數(shù)實(shí)現(xiàn)音頻的播放并通過網(wǎng)絡(luò)進(jìn)行傳送。這就能實(shí)現(xiàn)音頻的連續(xù)采集與傳送,達(dá)到了本次課程設(shè)計(jì)的目的。</p><p>  3.2 音頻在局域網(wǎng)中的傳輸</p><p>

69、  3.2.1 創(chuàng)建Socket派生類</p><p>  上面完成了對聲音的采集和處理,現(xiàn)在考慮怎樣與局域網(wǎng)內(nèi)的主機(jī)建立連接并把音頻數(shù)據(jù)發(fā)送出去。采用套接字(Socket)網(wǎng)絡(luò)編程接口來完成數(shù)據(jù)的收發(fā)工作。Socket是對通信端點(diǎn)的一種抽象,他提供了一種發(fā)送和接收數(shù)據(jù)的機(jī)制,在Visual C++6.0中Microsoft的基本類庫(Microsoft Foundation Class或MFC)提供了2個(gè)用于W

70、inSock編程的類,這2個(gè)類在不同程度上對WinSockAPI函數(shù)進(jìn)行了封裝,這樣在很大程度上簡化了工作。CAsyncSocket類是在低程度上對WinSock API的封裝,他提供低級接口。Csocket類是從CAsyncSocket類派生而來的,他提供高一級的抽象處理。本次課程設(shè)計(jì)中就創(chuàng)建了兩個(gè)基于Csocket的派生類CServerSocket和CClientSocket分別來對服務(wù)器和客戶端的Socket進(jìn)行處理。它們都直接繼

71、承Csocket類,因此能使用Csocket類的所有函數(shù)。此外針對服務(wù)器和客戶端的不同,還分別添加了各自的功能函數(shù)。</p><p>  在CServerSocket類中就加入了Init函數(shù),該函數(shù)主要實(shí)現(xiàn)服務(wù)器進(jìn)程相關(guān)的建立端口,監(jiān)聽客戶端連接等功能。還加入了OnAccept()函數(shù)來對新的游客請求連接服務(wù)器進(jìn)行處理。</p><p>  在CClientSocket類中則加入了Init

72、(),SendMessage(),CloseSocket()等函數(shù)分別來實(shí)現(xiàn)客戶端的初始化,發(fā)送信息,關(guān)閉端口等操作。</p><p>  3.2.2 自動獲得本機(jī)IP地址</p><p>  因?yàn)樵诰钟蚓W(wǎng)內(nèi)與其他主機(jī)進(jìn)行連接時(shí)必須要使用到對方的IP地址,只有將正確的主機(jī)IP地址作為一個(gè)參數(shù)傳入到本程序使用的connect函數(shù)中,才能與相應(yīng)的主機(jī)成功進(jìn)行連接,進(jìn)而進(jìn)行語音的傳輸。本次設(shè)計(jì)中

73、就實(shí)現(xiàn)了程序運(yùn)行時(shí)自動獲得本機(jī)的ip地址并通過IP地址控件顯示出來,這樣就免去了用戶專門去查詢自己電腦的IP地址的步驟,也體現(xiàn)了本設(shè)計(jì)人性化的一面。</p><p>  本次設(shè)計(jì)中將獲得自身電腦的IP地址的函數(shù)加入到了CClientSocket類中,要獲得自己主機(jī)的IP地址,首先需要得到主機(jī)名,獲得主機(jī)名的函數(shù)GetLocalHostName代碼如下:</p><p>  int CCli

74、entSocket::GetLocalHostName(CString &sHostName)//獲得本地計(jì)算機(jī)名稱</p><p><b>  {</b></p><p>  char szHostName[256];</p><p>  int nRetCode;</p><p>  nRetCode=ge

75、thostname(szHostName,sizeof(szHostName));</p><p>  if(nRetCode!=0)</p><p><b>  {</b></p><p><b>  //產(chǎn)生錯(cuò)誤</b></p><p>  sHostName=_T("沒有取得主機(jī)名!

76、");</p><p>  return GetLastError();</p><p><b>  }</b></p><p>  sHostName=szHostName;</p><p><b>  return 0;</b></p><p><b>

77、;  }</b></p><p>  該函數(shù)主要是調(diào)用gethostname()函數(shù)將本地計(jì)算機(jī)的名稱獲得,然后傳入到CString類型的參數(shù)sHostName中。</p><p>  得到主機(jī)名后,就可以使用GetIpAddress()函數(shù)得到主機(jī)的IP地址了,該函數(shù)的代碼如下:</p><p>  int CClientSocket::GetIpAd

78、dress(const CString &sHostName, CString &sIpAddress)</p><p><b>  {</b></p><p>  struct hostent FAR * lpHostEnt=gethostbyname(sHostName);</p><p>  if(lpHostEnt==N

79、ULL)</p><p><b>  {</b></p><p><b>  //產(chǎn)生錯(cuò)誤</b></p><p>  sIpAddress=_T("");</p><p>  return GetLastError();</p><p><b>

80、;  }</b></p><p><b>  //獲取IP</b></p><p>  LPSTR lpAddr=lpHostEnt->h_addr_list[0];</p><p>  if(lpAddr)</p><p><b>  {</b></p><p

81、>  struct in_addr inAddr;</p><p>  memmove(&inAddr,lpAddr,4);//轉(zhuǎn)換為標(biāo)準(zhǔn)格式</p><p>  sIpAddress=inet_ntoa(inAddr);//將一個(gè)IP轉(zhuǎn)換成一個(gè)互聯(lián)網(wǎng)標(biāo)準(zhǔn)點(diǎn)分格式的字符串</p><p>  if(sIpAddress.IsEmpty())</p

82、><p>  sIpAddress=_T("沒有取得IP地址!");</p><p><b>  }</b></p><p><b>  return 0;</b></p><p><b>  }</b></p><p>  從這段代碼可

83、以看出,這個(gè)函數(shù)利用到了前面得到的主機(jī)名作為參數(shù)調(diào)用gethostbyname函數(shù)得到一個(gè)記錄主機(jī)信息的結(jié)構(gòu)體hostent,然后從該結(jié)構(gòu)體中提取出主機(jī)的IP地址。由于得到的IP地址是網(wǎng)絡(luò)字節(jié)順序,后面又調(diào)用了memmove()和inet_ntoa()函數(shù)對該IP地址進(jìn)行了轉(zhuǎn)換。最后得到就是CString類型的互聯(lián)網(wǎng)標(biāo)準(zhǔn)點(diǎn)分格式的字符串。</p><p>  下圖3.1是程序運(yùn)行后的初始界面,從界面的右上方的IP

84、地址控件中可以看出本機(jī)的IP地址是192.168.1.104:</p><p>  圖 3.1 程序初始界面</p><p>  3.2.3 基于TCP協(xié)議的Socket編程</p><p>  進(jìn)行Socket編程需要首先選擇一定的協(xié)議,常用的協(xié)議有TCP、UDP、ARP等,本次設(shè)計(jì)中就選擇了面向連接的TCP協(xié)議,這是一種提供給用戶進(jìn)程的可靠的全雙工字節(jié)流面向連接

85、的協(xié)議。它要為用戶進(jìn)程提供虛電路服務(wù),并為數(shù)據(jù)可靠傳輸建立檢查。使用該協(xié)議能夠提供可靠的數(shù)據(jù)傳輸,能夠保證本設(shè)計(jì)語音的傳輸?shù)乜煽亢蜏?zhǔn)確。</p><p>  在TCP/IP網(wǎng)絡(luò)中兩個(gè)進(jìn)程間的相互作用的主機(jī)模式是客戶機(jī)/服務(wù)器模式(Client/Server model)。該模式的建立基于以下兩點(diǎn):1、非對等作用;2、通信完全是異步的??蛻魴C(jī)/服務(wù)器模式在操作過程中采取的是主動請示方式:</p>&l

86、t;p>  首先服務(wù)器方要先啟動,并根據(jù)請示提供相應(yīng)服務(wù):(過程如下)  1、打開一通信通道并告知本地主機(jī),它愿意在某一個(gè)公認(rèn)地址上接收客戶請求?! ?、等待客戶請求到達(dá)該端口?! ?、接收到重復(fù)服務(wù)請求,處理該請求并發(fā)送應(yīng)答信號。  4、返回第二步,等待另一客戶請求  5、關(guān)閉服務(wù)器?! 】蛻舴剑骸 ?、打開一通信通道,并連接到服務(wù)器所在主機(jī)的特定端口?! ?、向服務(wù)器發(fā)送服務(wù)請求報(bào)文,等待并接收應(yīng)答;繼續(xù)提出請

87、求…… 3、請求結(jié)束后關(guān)閉通信通道并終止。</p><p>  面向連接的套接字的系統(tǒng)調(diào)用時(shí)序圖如下圖3.2所示:</p><p>  圖3.2 系統(tǒng)調(diào)用時(shí)序圖</p><p>  本次課程設(shè)計(jì)中對語音進(jìn)行傳輸也是按照以上思路來編寫程序的,服務(wù)器端操作 socket(套接字)的主要步驟及使用到的主要函數(shù)如下:</p><p>  1、

88、建立Socket  初始化WinSock的動態(tài)連接庫后,需要在服務(wù)器端建立一個(gè)監(jiān)聽的Socket,為此可以調(diào)用Socket()函數(shù)用來建立這個(gè)監(jiān)聽的Socket,并定義此Socket所使用的通信協(xié)議。此函數(shù)調(diào)用成功返回Socket對象,失敗則返回INVALID_SOCKET(調(diào)用WSAGetLastError()可得知原因,所有WinSocket 的API函數(shù)都可以使用這個(gè)函數(shù)來獲取失敗的原因)?! OCKET PASCAL FA

89、R socket( int af, int type, int protocol )  參數(shù): af:目前只提供 PF_INET(AF_INET);     type:Socket 的類型 (SOCK_STREAM、SOCK_DGRAM);     protocol:通訊協(xié)定(如果使用者不指定則設(shè)為0);  如果要建立的是遵從TCP/IP協(xié)議的socket,第二個(gè)參數(shù)type應(yīng)為SOCK_STREAM,如為UDP(數(shù)據(jù)報(bào))的so

90、cket,應(yīng)為SOCK_DGRAM?! ?、綁定端口  接下來要為服務(wù)器端定義的這個(gè)監(jiān)聽的Socket指定一個(gè)</p><p>  name:Socket的地址值,這個(gè)地址必須是執(zhí)行這個(gè)程式所在機(jī)器的IP地址;      namelen:name的長度; </p><p>  如果使用者不在意地址或端口的值,那么可以設(shè)定地址為INADDR_ANY,及Port為0,Wind

91、ows Sockets 會自動將其設(shè)定適當(dāng)之地址及Port (1024 到 5000之間的值)。此后可以調(diào)用getsockname()函數(shù)來獲知其被設(shè)定的值?! ?、監(jiān)聽  當(dāng)服務(wù)器端的Socket對象綁定完成之后,服務(wù)器端必須建立一個(gè)監(jiān)聽的隊(duì)列來接收客戶端的連接請求。listen()函數(shù)使服務(wù)器端的Socket 進(jìn)入監(jiān)聽狀態(tài),并設(shè)定可以建立的最大連接數(shù)(目前最大值限制為 5, 最小值為1)。該函數(shù)調(diào)用成功返回0,否則返回SOCK

92、ET_ERROR?! nt PASCAL FAR listen( SOCKET s, int backlog );  參 數(shù): s:需要建立監(jiān)聽的Socket;      backlog:最大連接個(gè)數(shù);   服務(wù)器端的Socket調(diào)用完listen()后,如果此時(shí)客戶端調(diào)用connect()函數(shù)提出連接申請的話,Server 端必須再調(diào)用accept() 函數(shù),這樣服務(wù)器端和客戶端才算正式完成通信程序的連接動作。為了知道什么時(shí)

93、候客戶端提出連接要求,從</p><p>  客戶端操作 socket(套接字)的主要步驟如下:</p><p><b>  建立Socket</b></p><p>  這一步驟和服務(wù)器端一樣,依然使用了Socket()函數(shù)來建立Socket。</p><p>  使用connect()進(jìn)行連接</p>

94、<p>  建立好套接字后,就可以使用connect()函數(shù)來對服務(wù)器進(jìn)行連接了,只有成功連接</p><p>  之后才能進(jìn)行通訊,繼而才能進(jìn)行語音的傳輸。該函數(shù)的聲明如下:</p><p>  int PASCAL FAR connect(SOCKET s,const structaddr FAR*name,int namelen)參數(shù):s:標(biāo)識一未連接套接口的描述字。n

95、ame:將要進(jìn)行連接的端口名。namelen:名字長度。功能:建立與一個(gè)端口的連接。用于創(chuàng)建與指定外部端口的連接。s指定一個(gè)未連</p><p>  接的數(shù)據(jù)報(bào)或流類套接口。如套接口未被捆綁,則系統(tǒng)賦予本地關(guān)聯(lián)一個(gè)唯一的值,并設(shè)置套接口為已捆綁。若名字結(jié)構(gòu)中的地址為全零,則connect()將返回WSEADDRNOTAVAIL錯(cuò)誤。將服務(wù)器的IP地址和端口號作為參數(shù)傳入到該函數(shù)中,就能實(shí)現(xiàn)與特定主機(jī)的服務(wù)器端

96、和特定的端口號進(jìn)行連接。</p><p>  結(jié)束socket連接</p><p>  和服務(wù)器端一樣,依然調(diào)用closesocket()來結(jié)束socket連接。</p><p>  以上這些操作步驟主要是來完成對套接字的編程的,當(dāng)服務(wù)器和客戶端成功進(jìn)行連接后就可以進(jìn)行語音數(shù)據(jù)的傳輸了,進(jìn)行語音數(shù)據(jù)的傳輸主要用的是Csocket類提供的SendMessage()函數(shù)

97、,該函數(shù)能在服務(wù)器客戶端之間進(jìn)行一定量數(shù)據(jù)的傳輸。本次設(shè)計(jì)中除了用該函數(shù)實(shí)現(xiàn)語音數(shù)據(jù)的傳輸外,實(shí)現(xiàn)字符聊天功能時(shí)也用到了該函數(shù)來實(shí)現(xiàn)字符的發(fā)送功能。從前面分析的消息MM_WIM_DATA的響應(yīng)函數(shù)WriteBufferFull()中可以看出,也正是使用了此函數(shù)來將獲得的輸入音頻數(shù)據(jù)通過局域網(wǎng)發(fā)送到客戶端或服務(wù)器的。</p><p>  第四章 設(shè)計(jì)結(jié)果及分析</p><p><b&

98、gt;  4.1 設(shè)計(jì)結(jié)果</b></p><p>  在完成上一章的所有編碼之后,一個(gè)功能完備,界面友好的語音聊天平臺已經(jīng)出爐。</p><p>  首先運(yùn)行程序,本機(jī)IP自動獲取并且端口號自動生成為4000,也可以改為其他。主機(jī)點(diǎn)擊建立服務(wù)器,對話框?qū)︼@示出“Server Has Been Set OK!”如圖4.1所示。</p><p>  圖 4

99、.1 建立主機(jī)效果圖</p><p>  再主機(jī)建立好之后客戶端想要連接服務(wù)器,只需要知道服務(wù)器的IP地址還有服務(wù)器所設(shè)置的端口號。將這2項(xiàng)填入之后點(diǎn)解連接服務(wù)器按鈕,就會顯示“Client Connection Succeed”,其效果如圖4.2所示。</p><p>  圖 4.2 客戶連接成功效果圖</p><p>  由于這個(gè)系統(tǒng)是組播方式的,所以支持多個(gè)游

100、客進(jìn)入。當(dāng)已經(jīng)擁有一個(gè)點(diǎn)對點(diǎn)的聊天框架的時(shí)候,又有一個(gè)游客想要進(jìn)入,直接填寫服務(wù)器的IP和服務(wù)器的端口號便可以進(jìn)入聊天室。這個(gè)時(shí)候?yàn)榱烁嬷奶焓抑械某蓡T有新的成員加入,會群體播放一個(gè)消息為:一個(gè)游客進(jìn)入聊天室了。其效果如圖4.3所示。</p><p>  圖 4.3 多個(gè)游客進(jìn)入聊天室效果圖</p><p>  這個(gè)時(shí)候一個(gè)組播系統(tǒng)的多人聊天室已經(jīng)布局成功。想要進(jìn)行語音聊天只需要點(diǎn)擊語音聊

101、天按鈕就可以各自發(fā)言了。之后再次點(diǎn)擊這個(gè)按鈕可以停止發(fā)言但是可以聽見別人的發(fā)言,相當(dāng)于禁言的效果。如果不方便語音聊天,可以在編輯欄中輸入想要組播的消息,系統(tǒng)能夠自動識別是誰在說話,相當(dāng)于QQ群聊一樣,在制作這個(gè)功能的時(shí)候還遇見很多問題具體分析見下一節(jié)。</p><p><b>  4.2 錯(cuò)誤分析</b></p><p>  本次課程設(shè)計(jì)在設(shè)計(jì)文字聊天功能的時(shí)候,準(zhǔn)備

102、設(shè)計(jì)一個(gè)能夠像QQ那樣的顯示是哪一個(gè)IP地址的用戶在說話的功能,結(jié)果發(fā)現(xiàn)在對CString類型的字符串進(jìn)行操作的時(shí)候總是出現(xiàn)類型不匹配的錯(cuò)誤,導(dǎo)致添加發(fā)話人的這個(gè)功能實(shí)現(xiàn)不了。后來查閱資料對CString類型的字符串的一些自帶的函數(shù)進(jìn)行重新仔細(xì)地研究,發(fā)現(xiàn)有一個(gè)CString類型封裝好的函數(shù)能夠完美地實(shí)現(xiàn)這個(gè)功能所以添加了如下代碼:</p><p>  str.Format( "%s說:%s"

103、, ipStr, in);</p><p>  這句話的意思就是將ipStr字符串和in字符串按照ipStr說:in的格式組合成str字符串,其中ipStr是獲取的IP地址in是從編輯欄中獲取的輸入文字。這樣在對話框中顯示出str就是加工之后的語句了。效果如圖4.4所示:</p><p>  圖 4.4 顯示發(fā)話人效果圖</p><p>  除了這個(gè)問題比較難解決以

104、外,在進(jìn)行語音聊天的時(shí)候,在多個(gè)機(jī)器之間進(jìn)行調(diào)試也費(fèi)了不少功夫,若硬件未裝驅(qū)動,則打開硬件函數(shù)識別不了硬件的存在與否。有時(shí)候會打不開語音聊天。</p><p><b>  總 結(jié)</b></p><p>  通過本次綜合設(shè)計(jì),我進(jìn)一步理解和消化了音頻處理的相關(guān)理論知識和技術(shù)熟練度,如音頻提取、TCP/IP協(xié)議等,并且我的自主學(xué)習(xí)能力、動手能力和團(tuán)隊(duì)協(xié)作精神都得到了

105、顯著的提高,通過設(shè)計(jì)車牌識別系統(tǒng)的算法和程序,在不斷設(shè)計(jì)和嘗試中發(fā)現(xiàn)問題、解決問題,通過對算法的探索、研究與實(shí)踐并求得對問題的解決,從而達(dá)到了提高算法設(shè)計(jì)能力、程序編寫和項(xiàng)目開發(fā)的能力的目的。</p><p>  當(dāng)然在本次課程設(shè)計(jì)中,我也遇到了許多困難,比如說算法設(shè)計(jì)的合理性、傳播信息封裝的準(zhǔn)確率問題等等,但是我們通過互相學(xué)習(xí)、上網(wǎng)查找資料以及向老師、學(xué)長請教后,終于達(dá)到了目標(biāo)。但是我仍存在幾個(gè)問題沒有解決,例

106、如當(dāng)聊天環(huán)境嘈雜時(shí),對語音的識別不是很準(zhǔn)確。 </p><p>  對現(xiàn)實(shí)事物的設(shè)計(jì)不僅是對前面所學(xué)知識的一種檢驗(yàn),而且也是對自己能力的一種提高。通過這次設(shè)計(jì)使我明白了自己原來知識還比較欠缺。這個(gè)設(shè)計(jì)讓我學(xué)到了很多東西,涉及到方方面面的知識,在這整個(gè)過程中我們查閱了大量的資料,得到了老師和同學(xué)的幫助,我在此對他們表示謝意。在這期間遇到了很多困難,我知道做什么都不容易,只能塌下心來,一步一個(gè)腳印的去完成才行。我們學(xué)

107、習(xí)過計(jì)算機(jī)網(wǎng)絡(luò)這門課,并且在這個(gè)課程設(shè)計(jì)中應(yīng)用到了很多其中的知識。理論只有應(yīng)用到實(shí)際中才能學(xué)著更有意義。學(xué)習(xí)是一個(gè)長期積累的過程,在后的工作、生活中都應(yīng)該不斷的學(xué)習(xí),努力提高自己知識和綜合素質(zhì)。此外,還得出一個(gè)結(jié)論:知識必須通過應(yīng)用才能實(shí)現(xiàn)其價(jià)值!有些東西以為學(xué)會了,但真正到用的時(shí)候才發(fā)現(xiàn)是兩回事,所以我認(rèn)為只有到真正會用的時(shí)候才是真的學(xué)會了。在整個(gè)設(shè)計(jì)中我懂得了許多東西,也培養(yǎng)了我獨(dú)立工作的能力,以及團(tuán)隊(duì)協(xié)作的能力,樹立了信心,相信會

108、對今后的學(xué)習(xí)工作生活有非常重要的影響。同樣此次設(shè)計(jì)也大大提高了動手的能力,使我充分體會到了在創(chuàng)造過程中探索的艱難和成功時(shí)的喜悅。雖然這個(gè)設(shè)計(jì)做的并非對所以車牌都合適,但是在設(shè)計(jì)過 程中所學(xué)到的學(xué)習(xí)方法是我最大收獲</p><p><b>  致 謝</b></p><p>  感謝**學(xué)院給予了我們這次課程設(shè)計(jì)的機(jī)會,也感謝學(xué)校給我們提供實(shí)驗(yàn)室和實(shí)驗(yàn)電腦還有空調(diào)使

109、我們能在舒適優(yōu)秀的環(huán)境中進(jìn)行學(xué)習(xí)。在這次綜合設(shè)計(jì)的過程中,雖說不算太曲折,但是還是遇見了一些問題,在這里感謝曾經(jīng)幫助過我的**同學(xué)。還要感謝我的指導(dǎo)老師***老師,感謝他們對我的悉心的教導(dǎo)。</p><p><b>  參考文獻(xiàn)</b></p><p>  [1]陳堅(jiān),陳偉.Visual C++網(wǎng)絡(luò)高級編程[M].北京:人民郵電出版社,2001.</p>

110、<p>  [2]曹衍龍,劉海英.Visual C++網(wǎng)絡(luò)通信編程實(shí)用案例精選[M].北京:人民郵電出版社,2006.</p><p>  [3]曹章元,劉加明.Visual C++6.0類庫大全[M].北京:電子工業(yè)出版社,1999.</p><p>  [4]求是科技.Visual C++音視頻編解碼技術(shù)及實(shí)踐[M].北京:人民郵電出版社,2006.</p>

111、<p>  [5][美]JAMSA Kris.C/C++/c*程序員實(shí)用大全[M].北京:中國水利水電出版社,2002.</p><p>  [6][美]KRUGLINSKI David J.Visual C++技術(shù)內(nèi)幕[M].4版.北京:清華大學(xué)出版社,2001.</p><p>  [7]王華,葉愛亮.Visual C++6.0編程實(shí)例與技巧FM].北京:機(jī)械工業(yè)出版社,19

溫馨提示

  • 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. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論