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 = hex2Int(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 = hex2Int(formatsize); byte[] tmptag = composeByteArray(formattag); this.formatTag = hex2Int(tmptag); byte[] tmpchanels = composeByteArray(numchannels); this.num_Channels = hex2Int(tmpchanels); //声道数目,1--单声道;2--双声道 this.SamplesPerSec = hex2Int(samplespersec); //采样率 this.AvgBytesPerSec = hex2Int(avgbytespersec); //每秒所需字节数 byte[] tmpblockalign = composeByteArray(blockalign); this.BlockAlign = hex2Int(tmpblockalign); //数据块对齐单位(每个采样需要的字节数) byte[] tmpbitspersample = composeByteArray(bitspersample); this.BitsPerSample = hex2Int(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 = hex2Int(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 = hex2Int(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 } } double[] pressureWav = new double[wavdata.Count]; float[] preflt = new float[wavdata.Count]; //pressureWav = wavdata.ToArray(); double max = wavdata.Max();// double min = wavdata.Min(); for (int i = 0; i < wavdata.Count; i++) { pressureWav[i] = wavdata[i]; preflt[i] = (float)wavdata[i] / 1000; } } /// <summary> /// 将十六进制字符串转换为十进制数 /// </summary> /// <param name="hex"></param> /// <returns></returns> private int hex2Int(byte[] hex) { return hex[0] | (hex[1] << 8) | (hex[2] << 16) | (hex[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; } }
时间: 2024-10-01 04:22:03