王忠
摘 要: 使用WinCE系統的智能手持終端,在不穩定的無線網絡環境中使用UDP協議發送wav格式的音頻文件時,另一臺WinCE智能設備接收到的文件經常是不完整的,導致文件無法播放。針對這種網絡數據丟包現象,研究提高UDP協議可靠性的設計思路和實現方法,發現.wav文件頭中標識文件屬性的數據無法與接收到的文件數據實體對應,是造成無法正常播放的根本原因,因此對接收的文件的文件頭進行校正和復原工作,保證頭文件的各標識位對應數據的正確性,確保接收的聲音文件能正常播放。最后在嵌入式開發環境中進行了實現,驗證了這種方法的有效性。
關鍵詞: WinCE; UDP; wav文件; 智能手持終端
中圖分類號: TN911?34 文獻標識碼: A 文章編號: 1004?373X(2015)10?0049?03
0 引 言
WinCE是一個開放的嵌入式操作系統,是一種應用于手持智能終端的成熟的操作系統。在數據傳輸網絡中,UDP協議與其他協議相比,在速度上有一定的優勢,但也存在傳輸可靠性差的問題,因為UDP協議不提供數據傳送的保證機制。如果從發送方到接收方的傳遞過程中出現數據包的丟失,協議本身并不能做出任何檢測或提示,也不進行恢復。所以要想提高UDP協議的可靠性與安全性,就必須增加差錯處理、擁塞控制和安全控制等機制。在采用WinCE系統的手持智能設備中,由于經常是在不穩定的無線網絡環境中使用,當上層應用程序使用UDP協議傳輸wav音頻文件時,另一臺設備接收到的wav音頻文件由于丟包,經常無法正常播放,就失去了發送wav文件的意義。針對這種現象,研究使用WinCE系統的智能設備如何采用一種簡便易行的方法,保證wav文件能正常播放。
1 發送與接收過程分析
通過對UDP協議的研究,發現使用UDP協議在網絡傳輸過程中丟包是造成wav文件有損傳輸的主要原因;凡是不能正常播放的wav文件,其文件頭中標識文件屬性的數據無法與接收到的wav文件數據實體對應 [1]。
WinCE系統使用UDP協議發送與接收wav文件,需要開啟兩個線程[2],一個線程處理發送業務,一個線程處理接收業務。發送業務的處理主要是從麥克風獲取的wav文件進行處理,在發送之前拋棄wav文件的文件頭。這個處理過程的流程如圖1所示。
圖1 發送線程的處理流程
接收線程的主要是完成wav文件的接收。在接收之前需要先創建wav文件頭,然后把接收接收的數據放到已創建的wav頭之后,等待接收完成后對wav文件頭校正,保證wav文件的頭中的信息與wav文件是對應的[3?4]。接收線程的處理流程如圖2所示。
圖2 接收線程的處理流程
2 發送接收文件的實現過程
2.1 使用UDP協議發送之前的處理
通過對wav文件格式的研究發現,其文件頭的大小是44個字節,為了使處理更簡單,在開始傳輸之前,先要將wav文件讀入文件流中,舍棄文件頭的44個字節,從44個字節之后開始傳輸[5?6],主要實現代碼如下:
FileStream SoundStream = new FileStream(SoundPath, FileMode.Open); //創建文件流
SoundStream.Seek(44, SeekOrigin.Begin);
//將文件流的開始位置放到第44個字節之后
2.2 使用UDP協議接收過程
缺失了wav文件頭的音頻文件無法在WinCE設備上播放,在接收到音頻文件之前需要創建wav文件頭,在接收的過程中再把接收到的音頻數據寫入到創建的文件頭后面[7?9]。
///
///創建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; //采樣位數8或16
short BlockAlign = (short)(SChannels * (BitsPerSample / 8));
//單位采樣點的字節數
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); //數據塊
mWriter.Write(ChunkData);
mWriter.Write((int)0);
}
創建時要根據發送方發送的音頻文件的聲道數,采樣率,采樣位數對其中的數據進行修改。在傳輸完成后,還需要改變wav文件頭中標識音頻文件大小的數據[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 結 語
wav文件頭包含了wav音頻文件的屬性信息,因此使用UDP協議傳輸wav文件,要保證音頻文件能正常播放,就需要對wav的文件頭進行校正和復原處理。在實際使用UDP協議處理過程中,還有很多要注意的地方,比如使用UDP協議傳輸時數據報的長度有一定的限制。
參考文獻
[1] 王頎,趙世剛,張春壽.WAV文件的結構剖析[J].濟南教育學院學報,2000(3):29?31.
[2] 郭興吉. WAV波形文件的結構及其應用實踐[J].微計算機信息,2005,21(8):114?116.
[3] 王雪莉,盧才武,顧清華.無線定位技術及其在地下礦山中的應用[J].金屬礦山,2009(4):121?125.
[4] 陳昕志,王昆.基于嵌入式WinCE 6.0的網絡電視播放器研究[J].電視技術,2011,35(10):83?85.
[5] 何宗鍵.Windows CE嵌入式系統[M].北京:北京航空航天大學出版社,2006.
[6] 李曉燕,嚴殊.嵌入式流媒體播放器的設計與實現[J].通信技術,2007,40(12):403?404.
[7] 周錦才.可靠UDP協議的設計思路與實現方法[J].周口師范學院學報,2006,23(2):104?108.
[8] 王繼剛,顧國昌.可靠UDP數據傳輸協議的研究與設計[J].計算機工程與應用,2006,42(15):113?116.
[9] 靳海力,李俊.具有補發機制的增強型可靠UDP的實現[J].小型微型計算機系統,2010,31(5):904?907.
[10] 萬國府,劉貴全.衛星網絡中基于UDP的可靠數據傳輸協議[J].通信技術,2007,31(6):64?66.