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. Hbase记录-HBaseAdmin类

    HBaseAdmin是一个类表示管理.这个类属于org.apache.hadoop.hbase.client包.使用这个类,可以执行管理员任务.使用Connection.getAdmin()方法来获取 ...

  2. UESTC - 1167 一句话题意

    ---恢复内容开始--- 题目链接:https://vjudge.net/problem/UESTC-1167 请问从n*n的正方形左下角走到右上角且不越过对角线的情况总数模m的结果~ 分析: 还记得 ...

  3. 03-依赖倒置原则(DIP)

    1. 背景 类A是高层代码,类A直接依赖B,如果要将类A改为还要依赖C,则必须修改类A的代码来实现.在实际场景中,类A是高层,负责业务逻辑,类B和类C是低层模块,负责基本的原子操作,假如修改A,会给程 ...

  4. @ImportResource 导入Spring 的xml配置文件

    在配置类尚标注此注解,等同于spring配置文件中的 <import resource="beans.xml"/> Spring Boot里面没有Spring的配置文件 ...

  5. 2 Player and N Coin

    class Solution { public void printChoices(int[] A, int[][] C) { System.out.println("硬币列表如下:&quo ...

  6. Asp.net MVC Session过期异常的处理

    一.使用MVC中的Filter来对Session进行验证 (1)方法1: public class MyAuthorizeAttribute : FilterAttribute, IAuthoriza ...

  7. android 生成、pull解析xml文件

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools= ...

  8. 树形控件QTreeWidget

    import sys from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QApplication, QWidget, QTreeWidge ...

  9. Synchronized和lock的区别和用法

    一.synchronized和lock的用法区别 (1)synchronized(隐式锁):在需要同步的对象中加入此控制,synchronized可以加在方法上,也可以加在特定代码块中,括号中表示需要 ...

  10. 【python】pip安装报错UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 7: ordinal not in range(128)

    刚安装完python,准备pip安装第三方库的时候出现了一个错误: UnicodeDecodeError: ‘ascii’ code can’t decode byte 0xef in positio ...