首页 > 代码库 > WAV和PCM文件转换的程序

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 = http://www.mamicode.com/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);           }       }    }}

 

WAV和PCM文件转换的程序