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[];
byte[] size = new byte[];
byte[] type = new byte[]; byte[] formatid = new byte[];
byte[] formatsize = new byte[];
byte[] formattag = new byte[];
byte[] numchannels = new byte[];
byte[] samplespersec = new byte[];
byte[] avgbytespersec = new byte[];
byte[] blockalign = new byte[];
byte[] bitspersample = new byte[];
byte[] additionalinfo = new byte[]; //可选 byte[] factid = new byte[];
byte[] factsize = new byte[];
byte[] factdata = new byte[]; byte[] dataid = new byte[];
byte[] datasize = new byte[]; 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, , );
br.Read(size, , );
br.Read(type, , ); this.Id = getString(id, );
long longsize = bytArray2Int(size);//十六进制转为十进制
this.Size = longsize * 1.0;
this.Type = getString(type, );
#endregion #region Format Chunk
br.Read(formatid, , );
br.Read(formatsize, , );
br.Read(formattag, , );
br.Read(numchannels, , );
br.Read(samplespersec, , );
br.Read(avgbytespersec, , );
br.Read(blockalign, , );
br.Read(bitspersample, , );
if (getString(formatsize, ) == "")
{
br.Read(additionalinfo, , );
this.additionalInfo = getString(additionalinfo, ); //附加信息
} this.formatId = getString(formatid, ); 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[];
while (true)
{
br.Read(d_flag, , );
if (getString(d_flag, ) == "d")
{
break;
} }
byte[] dt_id = new byte[];
dt_id[] = d_flag[];
br.Read(dt_id, , );
this.dataId = getString(dt_id, ); br.Read(datasize, , ); this.dataSize = bytArray2Int(datasize); List<string> testl = new List<string>(); if (BitsPerSample == )
{ for (int i = ; i < this.dataSize; i++)
{
byte wavdt = br.ReadByte();
wavdata.Add(wavdt);
Console.WriteLine(wavdt);
}
}
else if (BitsPerSample == )
{
for (int i = ; i < this.dataSize/; 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[] | (bytArray[] << ) | (bytArray[] << ) | (bytArray[] << );
} /// <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 = ; 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[] { , , , };
tmptag[] = bt[];
tmptag[] = bt[];
return tmptag;
}
}

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

  1. Python 读取WAV文件并绘制波形图

    aa Python 读取WAV文件并绘制波形图 ffmpeg -i test_pcm_mulaw.wav -f wav -codec:a pcm_s16le -ar 8000 -ac 1 out.wa ...

  2. FreeSWITCH无法读取wav文件

    错误日志如下: -- :: Invalid file format [wav] /suite-espanola-op--leyenda.wav]! -- :: Can't open /usr/loca ...

  3. C#读取wav文件

    private void showWAVForm(string filepath) //此函数只能用于读取16bit量化单声道的WAV文件 { FileStream fs = new FileStre ...

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

    #!/usr/bin/python # encoding:utf-8 import pyaudio import wave CHUNK = 1024 # 从目录中读取语音 wf = wave.open ...

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

    资源下载 #本文PDF版下载 Python解析Wav文件并绘制波形的方法 #本文代码下载 Wav波形绘图代码 #本文实例音频文件night.wav下载 音频文件下载 (石进-夜的钢琴曲) 前言 在现在 ...

  6. C++标准库实现WAV文件读写

    在上一篇文章RIFF和WAVE音频文件格式中对WAV的文件格式做了介绍,本文将使用标准C++库实现对数据为PCM格式的WAV文件的读写操作,只使用标准C++库函数,不依赖于其他的库. WAV文件结构 ...

  7. wav文件系列_2_Python实现读写

    本文介绍了 Python 实现音频读写的方法.Python wave 模块提供便捷的 wav 文件操作.该模块并不支持压缩与解压,但支持单声道/立体声的转换. 参考: [1] wave — Read ...

  8. WAV文件读取

    WAV是一种以RIFF为基础的无压缩音频编码格式,该格式以Header.Format Chunk及Data Chunk三部分构成. 本文简要解析了各部分的构成要素,概述了如何使用C++对文件头进行解析 ...

  9. 《手把手教你》系列技巧篇(六十九)-java+ selenium自动化测试 - 读取csv文件(详细教程)

    1.简介 在实际测试中,我们不仅需要读取Excle,而且有时候还需要读取CSV类的文件.如何去读取CSV的文件,宏哥今天就讲解和分享一下,希望对你能够有所帮助.前面介绍了如何读取excel文件,本篇介 ...

随机推荐

  1. JAVA-大白话探索JVM-类加载器(一)

    JVM??? Java语言的一个非常重要的特点就是与平台的无关性.而使用Java虚拟机是实现这一特点的关键.JVM是Java Virtual Machine(Java虚拟机)的缩写,Java程序编译后 ...

  2. servlet 获取 post body 体用流读取为空的问题【转】

    引用自: http://www.zicheng.net/article/982028.htm 目前基于rest风格的很多API开始使用通过body data来传输来代替之前的key-value传输方式 ...

  3. logback异步输出日志(生产者消费者模型),并非批量写入日志。

    一直对logback异步输出日志误解为异步批量写入日志. 今天看了源代码. 首先logback的异步日志是如何配置的: <!-- 管理端用户行为日志异步输出,异步的log片段必须在同步段后面,否 ...

  4. Python中变量的属性以及判断方法

    1.变量的属性 在Python中,创建一个变量会给这个变量分配三种属性: id ,代表该变量在内存中的地址: type,代表该变量的类型: value,该变量的值: x = 10 print(id(x ...

  5. node.js 找不到 xxx 模块解决办法

    node.js找不到xxx 这个模块的解决方法. 按顺序来. 1.检查一下是否拼写错误. 2.这个模块是自己写的,是的话.检查一下路径是否正确. 3.如果是导入的模块.用 npm list这个命令输出 ...

  6. luogu P1627 [CQOI2009]中位数

    传送门 要求有多少个长度为奇数的区间满足某个数为区间中位数 这样的区间,大于中位数的数个数 等于 小于中位数的数个数 用类似于前缀和的方法,设\(X_i\)为\(i\)和数\(b\)形成的区间内,大于 ...

  7. 20165227《网络对抗技术》Exp0 Kali安装 Week1

    2018-2019-2 <网络对抗技术>Exp0 Kali安装 Week1 kali下载:镜像文件通过同学获得 kali具体安装步骤: 打开VMware,点击新建虚拟机,进行创建 创建完成 ...

  8. ubuntu14.04下 Kinect V2+Ros接口安装

    1. 首先git下载代码,放到主文件夹下面 git clone https://github.com/OpenKinect/libfreenect2.git 2. 然后安装依赖项如下,最好事先编译安装 ...

  9. 【转载】Hadoop mapreduce 实现原理

    1.  如何用通俗的方法解释MapReduce MapReduce是Google开源的三大技术之一,是对海量数据进行“分而治之”计算框架.为了简单的理解并讲述给客户理解.我们举下面的例子来说明. 首先 ...

  10. Linux文件系统3--打开文件

    1.前言 本文所述关于文件管理的系列文章主要是对陈莉君老师所讲述的文件系统管理知识讲座的整理. Linux可以支持不同的文件系统,它源于unix文件系统,也是unix文件系统的一大特色. 本文将以不同 ...