王忠
摘 要: 使用WinCE系統(tǒng)的智能手持終端,在不穩(wěn)定的無線網(wǎng)絡(luò)環(huán)境中使用UDP協(xié)議發(fā)送wav格式的音頻文件時,另一臺WinCE智能設(shè)備接收到的文件經(jīng)常是不完整的,導(dǎo)致文件無法播放。針對這種網(wǎng)絡(luò)數(shù)據(jù)丟包現(xiàn)象,研究提高UDP協(xié)議可靠性的設(shè)計思路和實現(xiàn)方法,發(fā)現(xiàn).wav文件頭中標(biāo)識文件屬性的數(shù)據(jù)無法與接收到的文件數(shù)據(jù)實體對應(yīng),是造成無法正常播放的根本原因,因此對接收的文件的文件頭進行校正和復(fù)原工作,保證頭文件的各標(biāo)識位對應(yīng)數(shù)據(jù)的正確性,確保接收的聲音文件能正常播放。最后在嵌入式開發(fā)環(huán)境中進行了實現(xiàn),驗證了這種方法的有效性。
關(guān)鍵詞: WinCE; UDP; wav文件; 智能手持終端
中圖分類號: TN911?34 文獻標(biāo)識碼: A 文章編號: 1004?373X(2015)10?0049?03
0 引 言
WinCE是一個開放的嵌入式操作系統(tǒng),是一種應(yīng)用于手持智能終端的成熟的操作系統(tǒng)。在數(shù)據(jù)傳輸網(wǎng)絡(luò)中,UDP協(xié)議與其他協(xié)議相比,在速度上有一定的優(yōu)勢,但也存在傳輸可靠性差的問題,因為UDP協(xié)議不提供數(shù)據(jù)傳送的保證機制。如果從發(fā)送方到接收方的傳遞過程中出現(xiàn)數(shù)據(jù)包的丟失,協(xié)議本身并不能做出任何檢測或提示,也不進行恢復(fù)。所以要想提高UDP協(xié)議的可靠性與安全性,就必須增加差錯處理、擁塞控制和安全控制等機制。在采用WinCE系統(tǒng)的手持智能設(shè)備中,由于經(jīng)常是在不穩(wěn)定的無線網(wǎng)絡(luò)環(huán)境中使用,當(dāng)上層應(yīng)用程序使用UDP協(xié)議傳輸wav音頻文件時,另一臺設(shè)備接收到的wav音頻文件由于丟包,經(jīng)常無法正常播放,就失去了發(fā)送wav文件的意義。針對這種現(xiàn)象,研究使用WinCE系統(tǒng)的智能設(shè)備如何采用一種簡便易行的方法,保證wav文件能正常播放。
1 發(fā)送與接收過程分析
通過對UDP協(xié)議的研究,發(fā)現(xiàn)使用UDP協(xié)議在網(wǎng)絡(luò)傳輸過程中丟包是造成wav文件有損傳輸?shù)闹饕颍环彩遣荒苷2シ诺膚av文件,其文件頭中標(biāo)識文件屬性的數(shù)據(jù)無法與接收到的wav文件數(shù)據(jù)實體對應(yīng) [1]。
WinCE系統(tǒng)使用UDP協(xié)議發(fā)送與接收wav文件,需要開啟兩個線程[2],一個線程處理發(fā)送業(yè)務(wù),一個線程處理接收業(yè)務(wù)。發(fā)送業(yè)務(wù)的處理主要是從麥克風(fēng)獲取的wav文件進行處理,在發(fā)送之前拋棄wav文件的文件頭。這個處理過程的流程如圖1所示。
圖1 發(fā)送線程的處理流程
接收線程的主要是完成wav文件的接收。在接收之前需要先創(chuàng)建wav文件頭,然后把接收接收的數(shù)據(jù)放到已創(chuàng)建的wav頭之后,等待接收完成后對wav文件頭校正,保證wav文件的頭中的信息與wav文件是對應(yīng)的[3?4]。接收線程的處理流程如圖2所示。
圖2 接收線程的處理流程
2 發(fā)送接收文件的實現(xiàn)過程
2.1 使用UDP協(xié)議發(fā)送之前的處理
通過對wav文件格式的研究發(fā)現(xiàn),其文件頭的大小是44個字節(jié),為了使處理更簡單,在開始傳輸之前,先要將wav文件讀入文件流中,舍棄文件頭的44個字節(jié),從44個字節(jié)之后開始傳輸[5?6],主要實現(xiàn)代碼如下:
FileStream SoundStream = new FileStream(SoundPath, FileMode.Open); //創(chuàng)建文件流
SoundStream.Seek(44, SeekOrigin.Begin);
//將文件流的開始位置放到第44個字節(jié)之后
2.2 使用UDP協(xié)議接收過程
缺失了wav文件頭的音頻文件無法在WinCE設(shè)備上播放,在接收到音頻文件之前需要創(chuàng)建wav文件頭,在接收的過程中再把接收到的音頻數(shù)據(jù)寫入到創(chuàng)建的文件頭后面[7?9]。
///
///創(chuàng)建wav文件
///
///
private void CreatewaveFile(string strFileName)
{
fswav = new FileStream(strFileName, FileMode.CreateNew);
mWriter = new BinaryWriter(fswav);
char[] ChunkRiff = { ′R′, ′I′, ′F′, ′F′ };
char[] ChunkType = { ′W′, ′A′, ′V′, ′E′ };
char[] ChunkFmt = { ′f′, ′m′, ′t′, ′ ′ };
char[] ChunkData = { ′d′, ′a′, ′t′, ′a′ };
short shPad = 1;
int nFormatChunkLength = 0x10;
int nLength = 0;
short shBytesPerSample = 1;
short SChannels = 1; //聲道 單聲道為1
int SamplesPerSecond = 11025;
//采樣率采樣率(單位:赫茲)典型值:11 025,22 050,44 100 Hz
short BitsPerSample = 8; //采樣位數(shù)8或16
short BlockAlign = (short)(SChannels * (BitsPerSample / 8));
//單位采樣點的字節(jié)數(shù)
int AverageBytesPerSecond = BlockAlign * SamplesPerSecond; // RIFF 塊
mWriter.Write(ChunkRiff); //4 B
mWriter.Write(nLength); //4 B
mWriter.Write(ChunkType); //4 B
//wavE塊
mWriter.Write(ChunkFmt); //4 B
mWriter.Write(nFormatChunkLength); //0x10 4 B
mWriter.Write(shPad); //2 B
mWriter.Write(SChannels);
mWriter.Write(SamplesPerSecond); //采樣率
mWriter.Write(AverageBytesPerSecond);
mWriter.Write(shBytesPerSample);
mWriter.Write(BitsPerSample); //數(shù)據(jù)塊
mWriter.Write(ChunkData);
mWriter.Write((int)0);
}
創(chuàng)建時要根據(jù)發(fā)送方發(fā)送的音頻文件的聲道數(shù),采樣率,采樣位數(shù)對其中的數(shù)據(jù)進行修改。在傳輸完成后,還需要改變wav文件頭中標(biāo)識音頻文件大小的數(shù)據(jù)[10]。
private void WriteSoundTail()
{
string SoundPathRecv = CodePath +
"\\tape\\aa\\Soundrecvwav";
long Fsize = new FileInfo(SoundPathRecv).Length;
mWriter.Seek(4, SeekOrigin.Begin);
mWriter.Write((int)Fsize?8);
mWriter.Seek(40, SeekOrigin.Begin);
mWriter.Write((int)Fsize?44);
mWriter.Close();
mWriter = null;
fswav = null;
}
3 結(jié) 語
wav文件頭包含了wav音頻文件的屬性信息,因此使用UDP協(xié)議傳輸wav文件,要保證音頻文件能正常播放,就需要對wav的文件頭進行校正和復(fù)原處理。在實際使用UDP協(xié)議處理過程中,還有很多要注意的地方,比如使用UDP協(xié)議傳輸時數(shù)據(jù)報的長度有一定的限制。
參考文獻
[1] 王頎,趙世剛,張春壽.WAV文件的結(jié)構(gòu)剖析[J].濟南教育學(xué)院學(xué)報,2000(3):29?31.
[2] 郭興吉. WAV波形文件的結(jié)構(gòu)及其應(yīng)用實踐[J].微計算機信息,2005,21(8):114?116.
[3] 王雪莉,盧才武,顧清華.無線定位技術(shù)及其在地下礦山中的應(yīng)用[J].金屬礦山,2009(4):121?125.
[4] 陳昕志,王昆.基于嵌入式WinCE 6.0的網(wǎng)絡(luò)電視播放器研究[J].電視技術(shù),2011,35(10):83?85.
[5] 何宗鍵.Windows CE嵌入式系統(tǒng)[M].北京:北京航空航天大學(xué)出版社,2006.
[6] 李曉燕,嚴(yán)殊.嵌入式流媒體播放器的設(shè)計與實現(xiàn)[J].通信技術(shù),2007,40(12):403?404.
[7] 周錦才.可靠UDP協(xié)議的設(shè)計思路與實現(xiàn)方法[J].周口師范學(xué)院學(xué)報,2006,23(2):104?108.
[8] 王繼剛,顧國昌.可靠UDP數(shù)據(jù)傳輸協(xié)議的研究與設(shè)計[J].計算機工程與應(yīng)用,2006,42(15):113?116.
[9] 靳海力,李俊.具有補發(fā)機制的增強型可靠UDP的實現(xiàn)[J].小型微型計算機系統(tǒng),2010,31(5):904?907.
[10] 萬國府,劉貴全.衛(wèi)星網(wǎng)絡(luò)中基于UDP的可靠數(shù)據(jù)傳輸協(xié)議[J].通信技術(shù),2007,31(6):64?66.