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. div显示提示信息【转】

    div显示提示信息 <body> <style type="text/css"> a.link{position:relative;} a.link div ...

  2. log4j入门

    日志是应用软件中不可缺少的部分,Apache的开源项目log4j是一个功能强大的日志组件,提供方便的日志记录.在apache网站:jakarta.apache.org/log4j 可以免费下载到Log ...

  3. android get或post及HttpClient与服务器数据交互

    1.Service package mydemo.mycom.demo2.service; import org.apache.http.HttpResponse; import org.apache ...

  4. Linux - 日志处理一

    Linux 日志处理 history # 历时命令默认1000条 HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S " # 让history命令显示具体时间 hi ...

  5. HNOI2018游记

    第一次参加本省省选,结果又是一次划水 Day 0 喝了一个小时鸡汤 大家看看人家钱学森(sheng) 竞赛生要多发展些爱好 不要一考完就fake,那种下考说"大佬AC辣!太强啦!月莫月莫月莫 ...

  6. C# 反编译项目修复

    1.反编译测试程序 1>.将测试程序添加到.NET Reflector 2>.选中测试程序后右键选择导出 2.反编译项目修复 1>.问题一 问题现象: base.AutoScaleM ...

  7. D- 泛型练习 ,继承,方法

    unit Unit3; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System ...

  8. 通过Application传递数据

    1:通过Application传递数据 假如有一个Activity A, 跳转到 Activity B ,并需要推荐一些数据,通常的作法是Intent.putExtra() 让Intent携带,或者有 ...

  9. Maven继承

    继承为了消除重复,可以把pom 中很多相同的配置提取出来:如:grouptId, version 等. 在使用的时候子工程直接继承父工程的依赖版本号,子工程中不再需要指定具体版本号,方便统一管控项目的 ...

  10. Keil MDK忽略警告:文件末尾空白行警告

    使用Keil MDK调试程序的时候,没有习惯在每个文件的末尾增加一个空白行,结果文件一多,编译时产生的警告就一大堆,排错都得用滚轮滚好久,就一个空白行还得出警告,烦死了,烦死了,烦死了!实在受不了了, ...