zoukankan      html  css  js  c++  java
  • WAV和PCM文件转换的程序

    using System;
    using System.IO;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    namespace Train.wav2pcm
    {
        public partial class frmMain : Form
        {
          
          /// <summary>
          /// ERROR MESSAGE
          /// </summary>
          const string ERRFILENOTEXITS = "File is Not Exits.";
          const string ERRFILEISNOTWAVE = "File is not Wava.";
            /// <summary>
            /// Wave Hander information
            /// </summary>
          struct HeaderType
            {
               public byte[]  riff;                 /*RIFF类资源文件头部 4byte*/
               public uint file_len;                /*文件长度4byte*/
               public byte[] wave;                  /*"WAVE"标志4byte*/
               public byte[] fmt;                   /*"fmt"标志4byte*/
               public uint NI1;                     /*过渡字节4byte*/
               public ushort format_type;           /*格式类别(10H为PCM形式的声音数据)2byte*/
               public ushort Channels;              /*Channels 1 = 单声道; 2 = 立体声2byte*/
               public uint frequency;               /*采样频率4byte*/
               public uint trans_speed;             /*音频数据传送速率4byte*/
               public ushort dataBlock;             /*数据块的调整数(按字节算的)2byte*/
               public ushort sample_bits;           /*样本的数据位数(8/16) 2byte*/
               public byte[] data;                  /*数据标记符"data" 4byte*/
               public uint wav_len;                 /*语音数据的长度 4byte*/
            }
            private HeaderType wavHander;       //定义一个头结构体
            private byte[] buff = new byte[44]; //header byte
            private byte[] databuff;            //data byte
            public frmMain()
            {
                InitializeComponent();
                InitialStruct();
            }
            /// <summary>
            /// 初始化结构体中的数组长度,分配内存
            /// </summary>
            private void InitialStruct()
            {
                wavHander.riff = new byte[4];//RIFF
                wavHander.wave = new byte[4];//WAVE
                wavHander.fmt = new byte[4];//fmt 
                wavHander.data = new byte[4];//data
            }
            /// <summary>
            /// 读取PCM中数据,
            /// </summary>
            /// <param name="filepath">文件路径</param>
            /// <returns>读取成功返回真</returns>
            private bool readPcm(string filepath)
            {
                String fileName = filepath;//临时保存文件名
                if (File.Exists(fileName) == false)//文件不存在
                {
                    throw new Exception(ERRFILENOTEXITS);
                }
                //自读方式打开
                FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None);
                if (file == null)//打开成功
                {
                    file.Close();//关闭文件
                    throw new Exception(ERRFILEISNOTWAVE);
                }
                int filelen =(int) file.Length;//获取文件长度
                databuff = new byte[filelen+44];//分配 内存
                file.Read(databuff, 44, filelen);//读取文件,保存在内存中
                file.Close();//关闭文件
                return true;
            }
            /// <summary>
            /// 为PCM文件构建文件头,准备转换为WAV文件
            /// </summary>
            /// <returns>构建成功返回真</returns>
            private bool InitHeader()
            {
                wavHander.riff = Encoding.ASCII.GetBytes("RIFF");   /*RIFF类资源文件头部 4byte*/
                wavHander.file_len=(uint) (databuff.Length);              /*文件长度4byte*/    
                wavHander.wave=Encoding.ASCII.GetBytes("WAVE");     /*"WAVE"标志4byte*/              
                wavHander.fmt=Encoding.ASCII.GetBytes("fmt ");      /*"fmt"标志4byte*/
                wavHander.NI1 =0x10;                               /*过渡字节4byte*/
                wavHander.format_type = 0x01;                       /*格式类别(10H为PCM形式的声音数据)2byte*/
                wavHander.Channels = 0x01;                          /*Channels 1 = 单声道; 2 = 立体声2byte*/
                wavHander.frequency = 0x1F40;                       /*采样频率4byte*/
                wavHander.trans_speed = 0x3E80;                     /*音频数据传送速率4byte*/
                wavHander.dataBlock = 0x02;                         /*数据块的调整数(按字节算的)2byte*/
                wavHander.sample_bits = 0x10;                       /*样本的数据位数(8/16) 2byte*/
                wavHander.data = Encoding.ASCII.GetBytes("data");   /*数据标记符"data" 4byte*/
                wavHander.wav_len =(uint) (databuff.Length-44);                /*语音数据的长度 4byte*/
                byte[] byt2;//临时变量 ,保存2位的整数
                byte[] byt4;//临时变量, 保存4位的整数
                Encoding.ASCII.GetBytes(Encoding.ASCII.GetString(wavHander.riff),0,4,databuff,0);/*RIFF类资源文件头部 4byte*/
                byt4 = BitConverter.GetBytes(wavHander.file_len); /*文件长度4byte*/   
                Array.Copy(byt4, 0, databuff, 4, 4);
                Encoding.ASCII.GetBytes(Encoding.ASCII.GetString(wavHander.wave), 0, 4, databuff, 8);/*"WAVE"标志4byte*/
                Encoding.ASCII.GetBytes(Encoding.ASCII.GetString(wavHander.fmt), 0, 4, databuff, 12);/*"fmt"标志4byte*/
                byt4 = BitConverter.GetBytes(wavHander.NI1);/*过渡字节4byte*/
                Array.Copy(byt4, 0, databuff,16,4);
                byt2 = BitConverter.GetBytes(wavHander.format_type);/*格式类别(10H为PCM形式的声音数据)2byte*/
                Array.Copy(byt2, 0, databuff, 20,2);
                byt2 = BitConverter.GetBytes(wavHander.Channels);/*Channels 1 = 单声道; 2 = 立体声2byte*/
                Array.Copy(byt2, 0, databuff, 22, 2);
                byt4 = BitConverter.GetBytes(wavHander.frequency);/*采样频率4byte*/
                Array.Copy(byt4, 0, databuff, 24, 4);
                byt4 = BitConverter.GetBytes(wavHander.trans_speed);/*音频数据传送速率4byte*/
                Array.Copy(byt4, 0, databuff, 28, 4);
                byt2 = BitConverter.GetBytes(wavHander.dataBlock);/*数据块的调整数(按字节算的)2byte*/
                Array.Copy(byt2, 0, databuff, 32, 2);
                byt2 = BitConverter.GetBytes(wavHander.sample_bits);/*样本的数据位数(8/16) 2byte*/
                Array.Copy(byt2, 0, databuff, 34, 2);
                Encoding.ASCII.GetBytes(Encoding.ASCII.GetString(wavHander.data), 0, 4, databuff, 36);/*数据标记符"data" 4byte*/
                byt4 = BitConverter.GetBytes(wavHander.wav_len); /*语音数据的长度 4byte*/
                Array.Copy(byt4, 0, databuff, 40, 4);
                return true;
            }
            /// <summary>
            /// 读取WAVE文件,包括文件头和数据部分
            /// </summary>
            /// <param name="filepath">文件路径</param>
            /// <returns>读取成功返回真</returns>
            private bool readWav(string filepath)
            {
                String fileName = filepath;//保存文件名
                if (File.Exists(fileName)==false)//文件不存在
                {
                    throw new Exception(ERRFILENOTEXITS);
                }
                //只读方式打开文件
                FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None);
                    if ( file==null ||  file.Length<44) //长度少于44,或者打开失败
                    {
                        file.Close();//
                        throw new Exception(ERRFILEISNOTWAVE);
                    }
                    file.Read(buff, 0, 44);//读取文件头
                if (fixedData(buff) == false)//按位置保存文件头信息到结构体中
                    throw new Exception(ERRFILEISNOTWAVE);
                databuff=new byte[wavHander.wav_len];//分配内存
                try
                {
                    file.Read(databuff, 0, databuff.Length);//读取文件数据去数据
                    return true; 
                }
                catch
                {
                    return false;
                }
                finally
                {
                    file.Close();//关闭文件
                }
            }
            /// <summary>
            /// 把文件头数组信息保存到结构体中
            /// </summary>
            /// <param name="pbuff">文件头数组</param>
            /// <returns>保存成功返回真</returns>
           bool  fixedData ( byte[] pbuff) 
            {
               
               Array.Copy(pbuff,0,wavHander.riff,0,4) ;//
               if (Encoding.ASCII.GetString(wavHander.riff) != "RIFF")//确定文件是WAVA类型
                   return false;
               wavHander.file_len=BitConverter.ToUInt32(pbuff,4);
               Array.Copy(pbuff,8,wavHander.wave,0,4) ;
               Array.Copy(pbuff,12,wavHander.fmt,0,4) ;
               wavHander.NI1 = BitConverter.ToUInt32(pbuff, 16);
               wavHander.format_type=BitConverter.ToUInt16(pbuff,20);
               wavHander.Channels=BitConverter.ToUInt16(pbuff,22);
               wavHander.frequency=BitConverter.ToUInt32(pbuff,24);
               wavHander.trans_speed=BitConverter.ToUInt32(pbuff,28);
               wavHander.dataBlock=BitConverter.ToUInt16(pbuff,32);
               wavHander.sample_bits=BitConverter.ToUInt16(pbuff,34);
               Array.Copy(pbuff,36,wavHander.data,0,4);
               wavHander.wav_len=BitConverter.ToUInt32(pbuff,40);
               return true;
            }
            /// <summary>
            /// 获取待转换的文件名 /button1 && button3
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
           private void button1_Click(object sender, EventArgs e)
           {
               Button b = (Button)sender;
               if (b.Name == "button1") txtWav2Pcm_wav.Text = getOpenFileName("WAV");
               else txtPcm2Wav_pcm.Text = getOpenFileName("PCM");
           }
            /// <summary>
            /// 打开对话框,获取被打开的文件路径
            /// </summary>
            /// <param name="type">WAV && PCM</param>
            /// <returns>文件名</returns>
           private string getOpenFileName(string type)
           {
               openFileDialog1.InitialDirectory = "c://";//初始路径
               openFileDialog1.Title = "";//初始文件名为空
               if (type == "WAV")//WAV文件被打开
                   openFileDialog1.Filter = "all file|*.*|wav|*.wav";
               else
                   openFileDialog1.Filter = "all file|*.*|pcm|*.pcm";
               openFileDialog1.FilterIndex = 2;
               if (openFileDialog1.ShowDialog() == DialogResult.OK) return openFileDialog1.FileName;
               else return "";
           }
           private string getSaveFileName(string type)
           {
               saveFileDialog1.InitialDirectory = "c://";//初始路径
               saveFileDialog1.Title = "";//初始文件名
               if (type == "WAV")//WAV文件被保存
                   saveFileDialog1.Filter = "all file|*.*|wav|*.wav";
               else
                   saveFileDialog1.Filter = "all file|*.*|pcm|*.pcm";
               saveFileDialog1.FilterIndex = 2;
               if (saveFileDialog1.ShowDialog() == DialogResult.OK) return saveFileDialog1.FileName;
               else return "";
           }
            /// <summary>
            /// 获取文件被保存的名 button2&& button4
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
           private void button2_Click(object sender, EventArgs e)
           {
               Button b = (Button)sender;
               if (b.Name == "button2") txtWav2Pcm_pcm.Text = getSaveFileName("PCM");
               else txtPcm2Wav_wav.Text = getSaveFileName("WAV");
           }
            /// <summary>
            /// wav->pcm
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
           private void btnWav2Pcm_Click(object sender, EventArgs e)
           {
               try
               {
                   if (readWav(txtWav2Pcm_wav.Text) == true)
                   {
                       WriteFile(txtWav2Pcm_pcm.Text, databuff);
                       lstMessage.Items.Add("PCM文件转换成功!" + System.DateTime.Now.ToString());
                   }
               }
               catch(Exception ex)
               {
                  lstMessage.Items.Add(ex.Message);
               }
           }
            /// <summary>
            /// 写文件操作
            /// </summary>
            /// <param name="filename">文件路径</param>
            /// <param name="pbuff">文件数据</param>
           private void WriteFile(string filename,byte[] pbuff)
           {
               if (File.Exists(filename) == true)
                   File.Delete(filename);
               FileStream sw=File.OpenWrite(filename);
               if (pbuff != null && sw != null)
               {
                   sw.Write(pbuff, 0, pbuff.Length);
                   sw.Close();
               }
           }
            /// <summary>
            /// pcm->wav
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
           private void btnPcm2Wav_Click(object sender, EventArgs e)
           {
               try
               {
                   if (readPcm(txtPcm2Wav_pcm.Text) && InitHeader())
                   {
                       WriteFile(txtPcm2Wav_wav.Text, databuff);
                       lstMessage.Items.Add("WAVA文件转换成功!" + System.DateTime.Now.ToString());
                   }
               }
               catch (Exception ex)
               {
                   lstMessage.Items.Add(ex.Message);
               }
           }
        }
    }
  • 相关阅读:
    POJ1087 A Plug for UNIX 网络流
    HDU4405 Aeroplane chess 期望DP
    POJ1062 昂贵的聘礼 区间枚举
    HDU4403 A very hard Aoshu problem 枚举
    HDU4407 Sum 容斥定理
    POJ2750 Potted Flower 线段树+DP
    软件项目开发流程以及人员职责
    10款最流行的开源Web设计工具
    C# 把\\r\\n替换为\r\n
    jquery validation 用到的输入验证正则表达式
  • 原文地址:https://www.cnblogs.com/BillBlog/p/4253560.html
Copyright © 2011-2022 走看看