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;
        }
    }
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM