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 = 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

C# 读取WAV文件(详细)的相关文章

FreeSWITCH无法读取wav文件

错误日志如下: 1 9003 2016-10-06 13:18:27.223464 [ERR] switch_core_file.c:260 Invalid file format [wav] for [/usr/local/freeswitch/sounds/music/8000/suite-espanola-op-47-leyenda.wav]! 2 9004 2016-10-06 13:18:27.223464 [ERR] mod_local_stream.c:354 Can't open

python读取wav文件并播放[pyaudio/wave]

#!/usr/bin/python # encoding:utf-8 import pyaudio import wave CHUNK = 1024 # 从目录中读取语音 wf = wave.open('mic4.wav', 'rb') # read data data = wf.readframes(CHUNK) # 创建播放器 p = pyaudio.PyAudio() # 获得语音文件的各个参数 FORMAT = p.get_format_from_width(wf.getsampwidt

读取wav文件绘制波形图

# -*- coding: utf-8 -*- import wave import pylab as pl import numpy as np from pyaudio import PyAudio,paInt16 def record(filename): #define of params NUM_SAMPLES = 2000 framerate = 16000 channels = 1 sampwidth = 2 #record time TIME = 10 def save_wave

C#读取wav文件

1 private void showWAVForm(string filepath) 2 { 3 FileStream fs = new FileStream(filepath,FileMode.Open); 4 fs.Read(new byte[42],0,42); 5 byte[] datasize = new byte[4]; 6 fs.Read(datasize,0,4); 7 int dtsize = hex2Int(datasize); //数据块部分数据的字节数 8 for (i

Python解析Wav文件并绘制波形的方法

资源下载 #本文PDF版下载 Python解析Wav文件并绘制波形的方法 #本文代码下载 Wav波形绘图代码 #本文实例音频文件night.wav下载 音频文件下载 (石进-夜的钢琴曲) 前言 在现在繁忙的生活中,我们经常会听些歌来放松一下自己,我们经常会从各种播放软件中听自己喜欢的歌,并且往往我们会下载一部分歌曲,而现在音频的种类也相当繁多,像是Wav,Mp3,FLAC,AAC等等很多格式,最近由于需要做一个能够分析Wav格式音频的波形来取得一些数据比如获取人录音时是否说完等等用途.本周先对解

wav 文件解析

WAVE文件格式说明表: 偏移地址 字节数 数据类型 内   容 文件头 00H 4 char "RIFF"标志 04H 4 long int 文件长度 08H 4 char "WAVE"标志 0CH 4 char "fmt"标志 10H 4 过渡字节(不定) 14H 2 int 格式类别(10H为PCM形式的声音数据) 16H 2 int 通道数,单声道为1,双声道为2 18H 4 int 采样率(每秒样本数),表示每个通道的播放速度, 1CH

Android音频开发(4):如何存储和解析wav文件

无论是文字.图像还是声音,都必须以一定的格式来组织和存储起来,这样播放器才知道以怎样的方式去解析这一段数据,例如,对于原始的图像数据,我们常见的格式有 YUV.Bitmap,而对于音频来说,最简单常见的格式就是 wav 格式了. wav 格式,与 bitmap 一样,都是微软开发的一种文件格式规范,它们都有一个相似之处,就是整个文件分为两部分,第一部分是"文件头",记录重要的参数信息,对于音频而言,就包括:采样率.通道数.位宽等等,对于图像而言,就包括:图像的宽高.色彩位数等等:第二部

Selenium+Python参数化:读取TXT文件

概述 从Selenium模块化一文中,可以看出参数化的必要性,本文来介绍下读取外部txt文件的方法. 如何打开文件 打开文件有以下两个函数可以应用: 1.open(file_name,access_mode) file_name: 文件路径及名称: access_mode :访问方式,具体参数如下,,未提供参数,则默认为r: r:表示读取: w:表示写入: a:表示添加: +: 表示读写: b:表示2进制访问; 2.file函数 file()内建函数它的功能等于open(),如下根据文档说明可知

Javascript写入txt和读取txt文件的方法

文章主要介绍了Javascript写入txt和读取txt文件的方法,需要的朋友可以参考下1. 写入 FileSystemObject可以将文件翻译成文件流. 第一步: 例: 复制代码 代码如下: Var fso=new ActiveXObject(Scripting.FileSystemObject); 创建一个可以将文件翻译成文件流的对象. 第二步:用于创建一个textStream 对象 括号里边有三个属性 1. 文件的绝对路径 2. 文件的常数 只读=1,只写=2 ,追加=8 等权限.(Fo