wave和pcm互轉

wav->pcm pcm->wav c#代碼:c#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace wavtopcm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            InitialStruct();
        }
        /// <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
       
        /// <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);
           }
       }
    }
}

相關文章
相關標籤/搜索