首页 > 代码库 > 利用C#将PCM格式的Wav进行对文件裁剪截取、淡入淡出、保存为音频文件相关详细代码解释

利用C#将PCM格式的Wav进行对文件裁剪截取、淡入淡出、保存为音频文件相关详细代码解释

/// <summary>      /// 文件裁剪截取      /// </summary> 健康知识平台重庆保胆取石 重庆胆结石医院     public class WavScissorHelper      {          public static bool GetWavFileScissor(string OriginalAudioFilePath, string DestinedAudioFilePath, int beginCutTime, int endCutTime, ref string errorInfo)          {              if (!File.Exists(OriginalAudioFilePath))              {                  errorInfo = string.Format("源文件:[{0}]不存在!", OriginalAudioFilePath);                  return false;              }              if (!Directory.Exists(Path.GetDirectoryName(DestinedAudioFilePath)))              {                  errorInfo = string.Format("文件夹:[{0}]不存在!", Path.GetDirectoryName(DestinedAudioFilePath));                  return false;              }              if ((beginCutTime < 0) || (endCutTime < 0)                  || (beginCutTime > endCutTime))              {                  errorInfo = string.Format("截取时间[{0}][{1}]有误!", beginCutTime, endCutTime);                  return false;              }              try              {                  WavFile oldFile = new WavFile(OriginalAudioFilePath);                  if (endCutTime > oldFile.PlayTime)                  {                      errorInfo = string.Format("结束截取时间[{0}]大于音频文件播放时间[{1}]!", endCutTime, oldFile.PlayTime);                      return false;                  }                  int timeSpan = endCutTime - beginCutTime;                    WavFile newFile = new WavFile(DestinedAudioFilePath);                  newFile.WavFormat = oldFile.WavFormat;                    byte[] newAudioBytes = new byte[oldFile.WavFormat.ByteRate * timeSpan];                  Array.Copy(oldFile.AudioDataBytes, oldFile.WavFormat.ByteRate * beginCutTime, newAudioBytes, 0, newAudioBytes.Length);                    newFile.WriteWavFile(newAudioBytes);                  return true;              }              catch (Exception e)              {                  return false;                }          }        }        /// <summary>      /// 淡入淡出处理      /// </summary>      public class WavFadeHelper      {          private WavFile _wavFile;                   public WavFadeHelper(string wavFilePath)          {              _wavFile = new WavFile(wavFilePath);          }              public bool FadeAtFirstSec(FadeMode fadeMode, long fadeLength)          {              return FadeAtSec(fadeMode, 0, fadeLength);          }            public bool FadeAtEndSec(FadeMode fadeMode, long fadeLength)          {              long totalTime = _wavFile.PlayTime;              if (totalTime < fadeLength)                  fadeLength = totalTime;              long startTime = totalTime - fadeLength;                return FadeAtSec(fadeMode, startTime, startTime + fadeLength);          }            public bool FadeAtSec(FadeMode fadeMode, long startSec, long endSec)          {              //总播放时间              long totalTime = _wavFile.PlayTime;                //采样位数                     // 16 bit 纵坐标为采样系数 细化为 2^16= 65535份 16位二进制表示 [ 0000 0000 0000 0000 ]              // 即为2Byte (每单位时间内产生 2Byte 的音频数据)                int byteNumPerSample = _wavFile.WavFormat.BitsPerSample / 8;                //采样频率              // 11025Hz 横坐标为采样频率 单位时间为: 1/11025 s                       //单位时间内产生的的音频数据大小为 2Byte * 11025Hz * 声道数                           //audioData 是按字节处理 16bit采样 每次获取两个字节进行处理                //开始位置 存储单元索引              long startIndex = startSec * byteNumPerSample * _wavFile.WavFormat.SampleRate;              if (startIndex % byteNumPerSample > 0)                  startIndex -= startIndex % byteNumPerSample;                //结束位置 存储单元索引              long endIndex = endSec * byteNumPerSample * _wavFile.WavFormat.SampleRate;              if (endIndex > _wavFile.AudioDataBytes.Length - 1)                  endIndex = _wavFile.AudioDataBytes.Length - 1;                //字节数组 音频数据              byte[] audioDatas = _wavFile.AudioDataBytes;                //初始衰减率              double rate = 1.0;                //对每个单位时间内的 样点幅值 进行衰减              //从淡化开始时间到结束时间共有 [ 采样频率 * 时间段(s) * 采样位数/8(Byte) ] 个存储单元              //每次取出 采样位数/8(Byte) 个存储单元进行衰减                // i 的值为每次衰减处理时的 字节读取位置 (索引)              for (int i = (int)startIndex; i < endIndex; i += byteNumPerSample)              {                  //衰减率的方向与淡入淡出有关                  //衰减率的大小与当前读取处理字节的索引位置有关                  if (fadeMode == FadeMode.FadeOut)                      rate = (double)(endIndex - i) / (endIndex - startIndex);                  else                      rate = (double)(i - startIndex) / (endIndex - startIndex);                    //单位时间内的字节数为1 即采用8bit采样位数  每次只需要对一个字节进行衰减                  if (byteNumPerSample == 1)                  {                      //获取需要衰减的字节值                      byte audioData =http://www.mamicode.com/ audioDatas[i];                        //进行衰减线性处理                      byte changedAudioData = http://www.mamicode.com/(byte)((double)audioData * rate);                      //byte changedAudioData = http://www.mamicode.com/Convert.ToByte((double)audioData * rate);>//对原来的值进行更改                      audioDatas[i] = changedAudioData;                  }                  else if (byteNumPerSample == 2)                  {                      //16bit 量化 每单位时间产生2Byte数据 因此取 2Byte 的数据进行衰减处理                      byte[] audioData = http://www.mamicode.com/new byte[2];                      Array.Copy(audioDatas, i, audioData, 0, 2);                        //单个样点幅值                      double sample = 0;                        //转换为整数进行线性处理                      sample = (double)BitConverter.ToInt16(audioData, 0) * rate;                        //转换为字节存储                      byte[] buffer = BitConverter.GetBytes(Convert.ToInt16(sample));                      if (!BitConverter.IsLittleEndian)                          Array.Reverse(buffer);                        Array.Copy(buffer, 0, audioDatas, i, 2);                  }              }              _wavFile.WriteWavFile(audioDatas);                return true;          }      }        /// <summary>      /// 淡入淡出模式      /// </summary>      public enum FadeMode      {          FadeIn,          FadeOut      }        /// <summary>      /// WAV 文件      /// </summary>      public class WavFile      {          private WavFormat _wavFormat;   //文件格式          private long _fileLength;       //文件长度          private string _filePath;       //文件路径          private byte[] _audioData;      //语音数据            private WavFile() { }          public WavFile(string filePath)          {              _filePath = filePath;          }            /// <summary>          /// 文件格式          /// </summary>          public WavFormat WavFormat          {              get              {                  if (_wavFormat == null)                      _wavFormat = GetWavFormat();                    return _wavFormat;              }              set { _wavFormat = value; }          }            /// <summary>          /// 文件大小          /// </summary>          public long FileLength          {              get              {                  if (_wavFormat == null)                      _wavFormat = GetWavFormat();                    return _fileLength;              }              set { _fileLength = value; }          }            /// <summary>          /// 播放时长          /// </summary>          public long PlayTime          {              get              {                  if (_wavFormat == null)                      _wavFormat = GetWavFormat();                    return _audioData.Length / _wavFormat.ByteRate;              }          }            /// <summary>          /// 语音数据          /// </summary>          public byte[] AudioDataBytes          {              get              {                  if (_wavFormat == null)                      _wavFormat = GetWavFormat();                    return _audioData;              }              set { _audioData =http://www.mamicode.com/ value; }          }            /// <summary>          /// 设置Wav文件格式          /// </summary>          /// <param name="bitsPerSample">采样位数</param>          /// <param name="channels">声道数</param>          /// <param name="sampleRate">采样率</param>          public void SetWavFormat(int bitsPerSample, int channels, int sampleRate)          {              _wavFormat = new WavFormat();              _wavFormat.BitsPerSample = bitsPerSample;              _wavFormat.Channels = channels;              _wavFormat.SampleRate = sampleRate;          }            /// <summary>          /// 写文件          /// </summary>          /// <param name="audioData">音频数据</param>          public void WriteWavFile(byte[] audioData)          {              WriteWavFile(_wavFormat, audioData, 0, audioData.Length);          }            /// <summary>          /// 写文件          /// </summary>          /// <param name="wavFormat">文件格式</param>          /// <param name="audioData">音频数据</param>          /// <param name="startIndex">audioData数组开始索引位置</param>          /// <param name="length">写入audioData数组长度</param>          public void WriteWavFile(WavFormat wavFormat, byte[] audioData, int startIndex, int length)          {              FileStream fs = null;              BinaryWriter bw = null;              try              {                  fs = new FileStream(_filePath, FileMode.Create, FileAccess.Write);                  bw = new BinaryWriter(fs);                  fs.Position = 0;                  bw.Write(new char[4] { R, I, F, F });                  //ChunkFileSize                  bw.Write((int)(length + 44 - 8));                  bw.Write(new char[8] { W, A, V, E, f, m, t,   });                  bw.Write((int)16);                  bw.Write((short)1);                  bw.Write((short)wavFormat.Channels);                  bw.Write(wavFormat.SampleRate);                  bw.Write((int)(wavFormat.SampleRate * ((wavFormat.BitsPerSample * wavFormat.Channels) / 8)));                  bw.Write((short)((wavFormat.BitsPerSample * wavFormat.Channels) / 8));                  bw.Write((short)wavFormat.BitsPerSample);                  bw.Write(new char[4] { d, a, t, a });                  bw.Write(length);                  bw.Write(audioData, startIndex, length);              }              finally              {                  if (bw != null)                      bw.Close();                  if (fs != null)                  {                      fs.Close();                      fs.Dispose();                  }              }          }            /// <summary>          /// 获取Wav文件格式          /// </summary>          /// <returns></returns>          private WavFormat GetWavFormat()          {              FileStream fs = null;              BinaryReader br = null;              WavFormat wavFormat = new WavFormat();                try              {                  fs = new FileStream(_filePath, FileMode.Open, FileAccess.Read);                  br = new BinaryReader(fs);                    _fileLength = fs.Length;                    fs.Position = 22;                  wavFormat.Channels = br.ReadInt16();                  fs.Position = 24;                  wavFormat.SampleRate = br.ReadInt32();                  fs.Position = 28;                  wavFormat.ByteRate = br.ReadInt32();                  fs.Position = 34;                  wavFormat.BitsPerSample = br.ReadInt16();                    //The audio data                  fs.Position = 44;                  int dataByteSize = (int)(fs.Length - 44);                  if (_audioData =http://www.mamicode.com/= null)                      _audioData = new byte[dataByteSize];                  fs.Read(_audioData, 0, dataByteSize);                }              finally              {                  if (br != null)                      br.Close();                  if (fs != null)                  {                      fs.Close();                      fs.Dispose();                  }              }              return wavFormat;          }      }        /// <summary>      /// WAV 文件格式      /// </summary>      public class WavFormat      {          /// <summary>          /// 采样位数          /// </summary>          public int BitsPerSample;          /// <summary>          /// 声道数          /// </summary>          public int Channels;          /// <summary>          /// 采样率          /// </summary>          public int SampleRate;          /// <summary>          /// 传输速率(播放速率)          /// </summary>          public long ByteRate;      }

 

利用C#将PCM格式的Wav进行对文件裁剪截取、淡入淡出、保存为音频文件相关详细代码解释