1. 程式人生 > >C#WAV音訊檔案轉化PCM資料檔案PCM轉化WAV音訊

C#WAV音訊檔案轉化PCM資料檔案PCM轉化WAV音訊

原始檔在下面連線

程式碼如下:

using System;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication2
{
    public partial class Form2 : 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 Form2()
        {
            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)
        {
                txtWav2Pcm_pcm.Text = getOpenFileName("WAV");
        }
        /// <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)
        {
            txtPcm2Wav_wav.Text = getSaveFileName("PCM");
        }
        /// <summary>
        /// wav->pcm
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnWav2Pcm_Click(object sender, EventArgs e)
        {
            
               
            
        }
        /// <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)
        {
           
        }

        private void button5_Click(object sender, EventArgs e)
        {
            if (readWav(txtWav2Pcm_pcm.Text.Trim()) == true)
            {
                WriteFile(txtPcm2Wav_wav.Text.Trim(), databuff);
                lstMessage.Items.Add("PCM檔案轉換成功!" + System.DateTime.Now.ToString());
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                if (readPcm(textBox1.Text) && InitHeader())
                {
                    WriteFile(textBox2.Text, databuff);
                    lstMessage.Items.Add("WAVA檔案轉換成功!" + System.DateTime.Now.ToString());
                }
            }
            catch (Exception ex)
            {
                lstMessage.Items.Add(ex.Message);
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            textBox1.Text = getOpenFileName("PCM");
        }

        private void button4_Click(object sender, EventArgs e)
        {
            textBox2.Text = getSaveFileName("WAV");
        }
    }
}


資源下載:點我跳轉