zoukankan      html  css  js  c++  java
  • C# 读取WAV文件(详细)

        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;
            }
        }
     
  • 相关阅读:
    UVa 1394 约瑟夫问题的变形
    UVa 572 油田(DFS求连通块)
    UVa 699 下落的树叶
    Prim求解最小生成树
    UVa 839 天平
    UVa 11988 破损的键盘(链表)
    UVa 442 矩阵链乘(栈)
    UVa 二叉树的编号(二叉树)
    UVa 12100打印队列(队列)
    约瑟夫圆桌问题
  • 原文地址:https://www.cnblogs.com/144823836yj/p/5989858.html
Copyright © 2011-2022 走看看