C#获取WAV文件的长度和结构

13 篇文章 0 订阅

时间是根据结构提的DATA的大小/每秒字节数

 

对于波形以后再帖出把。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.IO;
  5. namespace CopyDirectoryInfo
  6. {
  7.     public class WaveInfo
  8.     {
  9.         /// <summary>
  10.         /// 数据流
  11.         /// </summary>
  12.         private FileStream m_WaveData;
  13.        
  14.         private bool m_WaveBool = false;    
  15.         
  16.         private RIFF_WAVE_Chunk _Header = new RIFF_WAVE_Chunk();
  17.         private Format_Chunk _Format = new Format_Chunk();
  18.         private Fact_Chunk _Fact = new Fact_Chunk();
  19.         private Data_Chunk _Data = new Data_Chunk();
  20.         public WaveInfo(string WaveFileName)
  21.         {
  22.             m_WaveData = new FileStream(WaveFileName, FileMode.Open);
  23.             try
  24.             {
  25.                 LoadWave();
  26.                 m_WaveData.Close();
  27.             }
  28.             catch
  29.             {
  30.                 m_WaveData.Close();
  31.             }
  32.         }
  33.         private void LoadWave()
  34.         {
  35.             #region RIFF_WAVE_Chunk
  36.             byte[] _Temp4 = new byte[4];
  37.             byte[] _Temp2 = new byte[2];
  38.             m_WaveData.Read(_Temp4, 0, 4);
  39.             if (_Temp4[0] != _Header.szRiffID[0] || _Temp4[1] != _Header.szRiffID[1] || _Temp4[2] != _Header.szRiffID[2] || _Temp4[3] != _Header.szRiffID[3]) return;
  40.             m_WaveData.Read(_Temp4, 0, 4);
  41.             _Header.dwRiffSize = BitConverter.ToUInt32(_Temp4, 0);
  42.             m_WaveData.Read(_Temp4, 0, 4);
  43.             if (_Temp4[0] != _Header.szRiffFormat[0] || _Temp4[1] != _Header.szRiffFormat[1] || _Temp4[2] != _Header.szRiffFormat[2] || _Temp4[3] != _Header.szRiffFormat[3]) return;
  44.             
  45.             #endregion
  46.             #region Format_Chunk
  47.             m_WaveData.Read(_Temp4, 0, 4);
  48.             if (_Temp4[0] != _Format.ID[0] || _Temp4[1] != _Format.ID[1] || _Temp4[2] != _Format.ID[2]) return;
  49.             m_WaveData.Read(_Temp4, 0, 4);
  50.             _Format.Size = BitConverter.ToUInt32(_Temp4,0);
  51.             long _EndWave = _Format.Size + m_WaveData.Position ;
  52.             m_WaveData.Read(_Temp2, 0, 2);
  53.             _Format.FormatTag = BitConverter.ToUInt16(_Temp2, 0);
  54.             m_WaveData.Read(_Temp2, 0, 2);
  55.             _Format.Channels = BitConverter.ToUInt16(_Temp2, 0);
  56.             m_WaveData.Read(_Temp4, 0, 4);
  57.             _Format.SamlesPerSec = BitConverter.ToUInt32(_Temp4, 0);
  58.             m_WaveData.Read(_Temp4, 0, 4);
  59.             _Format.AvgBytesPerSec = BitConverter.ToUInt32(_Temp4, 0);
  60.             m_WaveData.Read(_Temp2, 0, 2);
  61.             _Format.BlockAlign = BitConverter.ToUInt16(_Temp2, 0);
  62.             m_WaveData.Read(_Temp2, 0, 2);
  63.             _Format.BitsPerSample = BitConverter.ToUInt16(_Temp2, 0);
  64.             m_WaveData.Position += _EndWave - m_WaveData.Position;
  65.             #endregion
  66.             m_WaveData.Read(_Temp4, 0, 4);
  67.             if (_Temp4[0] == _Fact.ID[0] && _Temp4[1] == _Fact.ID[1] && _Temp4[2] == _Fact.ID[2] && _Temp4[3] == _Fact.ID[3])
  68.             {
  69.                 #region  Fact_Chunk
  70.                 m_WaveData.Read(_Temp4, 0, 4);
  71.                 _Fact.Size = BitConverter.ToUInt32(_Temp4, 0);
  72.                 m_WaveData.Position += _Fact.Size;
  73.                 #endregion
  74.                 m_WaveData.Read(_Temp4, 0, 4);
  75.             }
  76.             if (_Temp4[0] == _Data.ID[0] && _Temp4[1] == _Data.ID[1] && _Temp4[2] == _Data.ID[2] && _Temp4[3] == _Data.ID[3])
  77.             {
  78.                 #region Data_Chunk
  79.                 m_WaveData.Read(_Temp4, 0, 4);
  80.                 _Data.Size = BitConverter.ToUInt32(_Temp4, 0);
  81.                 _Data.FileBeginIndex = m_WaveData.Position;
  82.                 _Data.FileOverIndex = m_WaveData.Position + _Data.Size;
  83.                 m_Second = (double)_Data.Size / (double)_Format.AvgBytesPerSec;
  84.                 #endregion
  85.             }
  86.           
  87.             m_WaveBool = true;
  88.         }
  89.         #region 文件定义
  90.         /// <summary>
  91.         /// 文件头
  92.         /// </summary>
  93.         private class RIFF_WAVE_Chunk
  94.         {
  95.             /// <summary>
  96.             /// 文件前四个字节 为RIFF
  97.             /// </summary>
  98.             public byte[] szRiffID = new byte[] { 0x52,0x49,0x46,0x46};   // 'R','I','F','F'
  99.             /// <summary>
  100.             /// 数据大小 这个数字等于+8 =文件大小
  101.             /// </summary>
  102.             public uint dwRiffSize = 0;
  103.             /// <summary>
  104.             ///WAVE文件定义 为WAVE
  105.             /// </summary>
  106.             public byte[] szRiffFormat = new byte[] { 0x57,0x41,0x56,0x45}; // 'W','A','V','E'         
  107.         }
  108.         /// <summary>
  109.         /// 声音内容定义
  110.         /// </summary>
  111.         private class Format_Chunk
  112.         {
  113.             /// <summary>
  114.             /// 固定为  是"fmt "字后一位为0x20
  115.             /// </summary>
  116.             public byte[] ID= new byte[]{0x66,0x6D,0x74,0x20};
  117.             /// <summary>
  118.             /// 区域大小
  119.             /// </summary>
  120.             public uint Size =0;
  121.             /// <summary>
  122.             /// 记录着此声音的格式代号,例如1-WAVE_FORMAT_PCM, 2-WAVE_F0RAM_ADPCM等等。 
  123.             /// </summary>
  124.             public ushort FormatTag=1;
  125.             /// <summary>
  126.             /// 声道数目,1--单声道;2--双声道
  127.             /// </summary>
  128.             public ushort Channels=2;
  129.             /// <summary>
  130.             /// 采样频率  一般有11025Hz(11kHz)、22050Hz(22kHz)和44100Hz(44kHz)三种
  131.             /// </summary>
  132.             public uint SamlesPerSec=0;
  133.             /// <summary>
  134.             /// 每秒所需字节数
  135.             /// </summary>
  136.             public uint AvgBytesPerSec=0;
  137.             /// <summary>
  138.             /// 数据块对齐单位(每个采样需要的字节数)
  139.             /// </summary>
  140.             public ushort BlockAlign=0;
  141.             /// <summary>
  142.             /// 音频采样大小 
  143.             /// </summary>
  144.             public ushort BitsPerSample=0;
  145.             /// <summary>
  146.             /// ???
  147.             /// </summary>
  148.             public byte[] Temp = new byte[2];
  149.         }
  150.         /// <summary>
  151.         /// FACT
  152.         /// </summary>
  153.         private class Fact_Chunk
  154.         {
  155.             /// <summary>
  156.             /// 文件前四个字节 为fact
  157.             /// </summary>
  158.             public byte[] ID = new byte[] { 0x66, 0x61, 0x63, 0x74 };   // 'f','a','c','t'
  159.             /// <summary>
  160.             /// 数据大小
  161.             /// </summary>
  162.             public uint Size = 0;
  163.             /// <summary>
  164.             /// 临时数据
  165.             /// </summary>
  166.             public byte[] Temp;
  167.         }
  168.         /// <summary>
  169.         /// 数据区
  170.         /// </summary>
  171.         private class Data_Chunk
  172.         {
  173.             /// <summary>
  174.             /// 文件前四个字节 为RIFF
  175.             /// </summary>
  176.             public byte[] ID = new byte[] { 0x64, 0x61, 0x74, 0x61 };   // 'd','a','t','a'
  177.             /// <summary>
  178.             /// 大小
  179.             /// </summary>
  180.             public uint Size = 0;             
  181.             /// <summary>
  182.             /// 开始播放的位置
  183.             /// </summary>
  184.             public long FileBeginIndex = 0;
  185.             /// <summary>
  186.             /// 结束播放的位置
  187.             /// </summary>
  188.             public long FileOverIndex = 0;
  189.         }
  190.         #endregion
  191.         #region 属性
  192.         /// <summary>
  193.         /// 是否成功打开文件
  194.         /// </summary>
  195.         public bool WaveBool { get { return m_WaveBool; } }
  196.         private double m_Second = 0;
  197.         /// <summary>
  198.         /// 秒单位
  199.         /// </summary>
  200.         public double Second { get { return m_Second; } }
  201.         /// <summary>
  202.         /// 格式
  203.         /// </summary>
  204.         public string FormatTag
  205.         {
  206.             get
  207.             {
  208.                 switch (_Format.FormatTag)
  209.                 {
  210.                     case 1:
  211.                         return "PCM";
  212.                     case 2:
  213.                         return "Microsoft ADPCM";
  214.                     default:
  215.                         return "Un";
  216.                 }
  217.             }
  218.         }
  219.         /// <summary>
  220.         /// 频道
  221.         /// </summary>
  222.         public ushort Channels {get {return _Format.Channels;}}
  223.         /// <summary>
  224.         /// 采样级别
  225.         /// </summary>
  226.         public string SamlesPerSec 
  227.         {
  228.             get
  229.             {
  230.                 switch (_Format.SamlesPerSec)
  231.                 {
  232.                     case 11025:
  233.                         return "11kHz";
  234.                     case 22050:
  235.                         return "22kHz";
  236.                     case 44100:
  237.                         return "44kHz";
  238.                     default:
  239.                         return _Format.SamlesPerSec.ToString()+"Hz";
  240.                 }
  241.             }
  242.         }
  243.         /// <summary>
  244.         /// 采样大小
  245.         /// </summary>
  246.         public ushort BitsPerSample{get {return _Format.BitsPerSample;}}
  247.         #endregion
  248.     }
  249. }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值