zoukankan      html  css  js  c++  java
  • 利用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 = audioDatas[i];
     
     
     
                         //进行衰减线性处理
     
                         byte changedAudioData = (byte)((double)audioData * rate);
     
                         //byte changedAudioData = Convert.ToByte((double)audioData * rate);
     
     
     
                         //对原来的值进行更改
     
                         audioDatas[i] = changedAudioData;
     
                     }
     
                     else if (byteNumPerSample == 2)
     
                     {
     
                         //16bit 量化 每单位时间产生2Byte数据 因此取 2Byte 的数据进行衰减处理
     
                         byte[] audioData = 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 = 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 == 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;
     
         }
  • 相关阅读:
    Firefly多路人脸识别解决方案
    Jquery插件开发之图片放大镜效果(仿淘宝)
    html5 Game开发系列文章之 零[开篇]
    html5 Game开发系列文章之 一 精灵(上)
    html5 Game开发系列文章之 三 搭建基本游戏框架(代码封装)
    html5 Game开发系列文章之 二 精灵(下)
    JQEURY 插件之 简洁小提示框效果[ToolTips]
    18位身份证和组织机构代码校验ORACLE函数
    linux下apache+SVN搭建完美版
    MYSQL的常用命令和增删改查语句和数据类型
  • 原文地址:https://www.cnblogs.com/liushunli/p/4020071.html
Copyright © 2011-2022 走看看