class WAVReader { #region RIFF WAVE Chunk private string Id; //文件標識 private double Size; //文件大小 private string Type; //文件類型 #endregion #region Format Chunk private string formatId; private double formatSize; //數值為16或18,18則最后又附加信息 private int formatTag; private int num_Channels; //聲道數目,1--單聲道;2--雙聲道 private int SamplesPerSec; //采樣率 private int AvgBytesPerSec; //每秒所需字節數 private int BlockAlign; //數據塊對齊單位(每個采樣需要的字節數) private int BitsPerSample; //每個采樣需要的bit數 private string additionalInfo; //附加信息(可選,通過Size來判斷有無) /* * 以'fmt'作為標示。一般情況下Size為16,此時最后附加信息沒有; * 如果為18則最后多了2個字節的附加信息。 * 主要由一些軟件制成的wav格式中含有該2個字節的附加信息 */ #endregion #region Fact Chunk(可選) /* * Fact Chunk是可選字段,一般當wav文件由某些軟件轉化而成,則包含該Chunk。 */ private string factId; private int factSize; private string factData; #endregion #region Data Chunk private string dataId; private int dataSize; private List<double> wavdata = new List<double>(); //默認為單聲道 #endregion /// <summary> /// 讀取波形文件並顯示 /// </summary> /// <param name="filePath"></param> public void ReadWAVFile(string filePath) { if (filePath == "") return; byte[] id = new byte[4]; byte[] size = new byte[4]; byte[] type = new byte[4]; byte[] formatid = new byte[4]; byte[] formatsize = new byte[4]; byte[] formattag = new byte[2]; byte[] numchannels = new byte[2]; byte[] samplespersec = new byte[4]; byte[] avgbytespersec = new byte[4]; byte[] blockalign = new byte[2]; byte[] bitspersample = new byte[2]; byte[] additionalinfo = new byte[2]; //可選 byte[] factid = new byte[4]; byte[] factsize = new byte[4]; byte[] factdata = new byte[4]; byte[] dataid = new byte[4]; byte[] datasize = new byte[4]; using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { using (BinaryReader br = new BinaryReader(fs, Encoding.UTF8)) { #region RIFF WAVE Chunk br.Read(id, 0, 4); br.Read(size, 0, 4); br.Read(type, 0, 4); this.Id = getString(id, 4); long longsize = bytArray2Int(size);//十六進制轉為十進制 this.Size = longsize * 1.0; this.Type = getString(type, 4); #endregion #region Format Chunk br.Read(formatid, 0, 4); br.Read(formatsize, 0, 4); br.Read(formattag, 0, 2); br.Read(numchannels, 0, 2); br.Read(samplespersec, 0, 4); br.Read(avgbytespersec, 0, 4); br.Read(blockalign, 0, 2); br.Read(bitspersample, 0, 2); if (getString(formatsize, 2) == "18") { br.Read(additionalinfo, 0, 2); this.additionalInfo = getString(additionalinfo, 2); //附加信息 } this.formatId = getString(formatid, 4); this.formatSize = bytArray2Int(formatsize); byte[] tmptag = composeByteArray(formattag); this.formatTag = bytArray2Int(tmptag); byte[] tmpchanels = composeByteArray(numchannels); this.num_Channels = bytArray2Int(tmpchanels); //聲道數目,1--單聲道;2--雙聲道 this.SamplesPerSec = bytArray2Int(samplespersec); //采樣率 this.AvgBytesPerSec = bytArray2Int(avgbytespersec); //每秒所需字節數 byte[] tmpblockalign = composeByteArray(blockalign); this.BlockAlign = bytArray2Int(tmpblockalign); //數據塊對齊單位(每個采樣需要的字節數) byte[] tmpbitspersample = composeByteArray(bitspersample); this.BitsPerSample = bytArray2Int(tmpbitspersample); // 每個采樣需要的bit數 #endregion #region Fact Chunk //byte[] verifyFactChunk = new byte[2]; //br.Read(verifyFactChunk, 0, 2); //string test = getString(verifyFactChunk, 2); //if (getString(verifyFactChunk, 2) == "fa") //{ // byte[] halffactId = new byte[2]; // br.Read(halffactId, 0, 2); // byte[] factchunkid = new byte[4]; // for (int i = 0; i < 2; i++) // { // factchunkid[i] = verifyFactChunk[i]; // factchunkid[i + 2] = halffactId[i]; // } // this.factId = getString(factchunkid, 4); // br.Read(factsize, 0, 4); // this.factSize = bytArray2Int(factsize); // br.Read(factdata, 0, 4); // this.factData = getString(factdata, 4); //} #endregion #region Data Chunk byte[] d_flag = new byte[1]; while (true) { br.Read(d_flag, 0, 1); if (getString(d_flag, 1) == "d") { break; } } byte[] dt_id = new byte[4]; dt_id[0] = d_flag[0]; br.Read(dt_id, 1, 3); this.dataId = getString(dt_id, 4); br.Read(datasize, 0, 4); this.dataSize = bytArray2Int(datasize); List<string> testl = new List<string>(); if (BitsPerSample == 8) { for (int i = 0; i < this.dataSize; i++) { byte wavdt = br.ReadByte(); wavdata.Add(wavdt); Console.WriteLine(wavdt); } } else if (BitsPerSample == 16) { for (int i = 0; i < this.dataSize/2; i++) { short wavdt = br.ReadInt16(); wavdata.Add(wavdt); Console.WriteLine(wavdt); } } #endregion } } } /// <summary> /// 數字節數組轉換為int /// </summary> /// <param name="bytArray"></param> /// <returns></returns> private int bytArray2Int(byte[] bytArray) { return bytArray[0] | (bytArray[1] << 8) | (bytArray[2] << 16) | (bytArray[3] << 24); } /// <summary> /// 將字節數組轉換為字符串 /// </summary> /// <param name="bts"></param> /// <param name="len"></param> /// <returns></returns> private string getString(byte[] bts, int len) { char[] tmp = new char[len]; for (int i = 0; i < len; i++) { tmp[i] = (char)bts[i]; } return new string(tmp); } /// <summary> /// 組成4個元素的字節數組 /// </summary> /// <param name="bt"></param> /// <returns></returns> private byte[] composeByteArray(byte[] bt) { byte[] tmptag = new byte[4] { 0, 0, 0, 0 }; tmptag[0] = bt[0]; tmptag[1] = bt[1]; return tmptag; } }