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);
           }
       }
    }
}

WAV和PCM文件转换的程序的更多相关文章

  1. WebRTC录音(2)-录音文件转换成WAV格式

    以下是源码,大路货,从网上找的. 但是,这个东西在MacOS上是有问题的,原因在最后,都是泪啊. #include <stdio.h> #include <string.h> ...

  2. (原创)speex与wav格式音频文件的互相转换(二)

    之前写过了如何将speex与wav格式的音频互相转换,如果没有看过的请看一下连接 http://www.cnblogs.com/dongweiq/p/4515186.html 虽然自己实现了相关的压缩 ...

  3. (原创)speex与wav格式音频文件的互相转换

    我们的司信项目又有了新的需求,就是要做会议室.然而需求却很纠结,要继续按照原来发语音消息那样的形式来实现这个会议的功能,还要实现语音播放的计时,暂停,语音的拼接,还要绘制频谱图等等. 如果是wav,m ...

  4. ocx文件转换成C#程序引用的DLL

    将ocx文件转换成C#程序引用的DLL文件的办法  将ocx文件转换成C#程序引用的DLL文件的办法,需要的朋友可以参考一下  1.打开VS2008或VS2010命令提示符(此例用VS2008) 将o ...

  5. 【数据预处理】TIMIT语料库WAV文件转换

    1 问题描述 这两天复现代码.先构造数据集,纯净语音.不同噪声.不同SNR的混合语音.其中纯净语音由两部分组成,IEEE corpus和TIMIT. 一开始我用MATLAB中的audioread读取音 ...

  6. ffmpeg音频文件转换之使用stdin/stdout或BytesIO对象输入输出

    最近在搞小程序录音,然后使用百度接口做语音识别. 小程序目前仅支持mp3和aac编码格式.虽然百度接口提供的m4a格式支持能直接识别小程序的录音文件,但由于自己还有其他一系列需求(比如直接读取数据,根 ...

  7. .net amr格式文件转换成mp3格式文件的方法

    前言:winform端对于音频文件的格式多有限制,大多数不支持amr格式的文件的播放.但是,手机端传过来的音频文件大多数是amr格式的文件,所以,要想在winform客户端支持音频文件的播放,可以通过 ...

  8. WAV和PCM的关系和区别

    什么是WAV和PCM? WAV:wav是一种无损的音频文件格式,WAV符合 PIFF(Resource Interchange File Format)规范.所有的WAV都有一个文件头,这个文件头音频 ...

  9. net 预览文件 转换文件

    预览SWF文件 swfobject.js  (google浏览器 会阻止 需设置) @{ ViewBag.Title = "PdfPreview"; Layout = " ...

随机推荐

  1. 【做题】Codeforces Round #453 (Div. 1) D. Weighting a Tree——拆环

    前言:结论题似乎是我的硬伤…… 题意是给你一个无向图,已知连接到每一个点的边的权值和(为整数,且属于区间[-n,n]),需要求出每条边权值的一个合法解(都要是在区间[-2*n^2,2*n^2]内的整数 ...

  2. [转]web高级开发的成长之路

    读了这篇文章之后感觉蛮受启发的,在此分享一下,献给和我一样处于困惑的朋友. 正文如下: 本人也是coding很多年,虽然很失败,但也总算有点失败的心得,不过我在中国,大多数程序员都是像我一样,在一直走 ...

  3. 【修改密码】Linux下修改Mysql的用户(root)的密码

    修改的用户都以root为列.一.拥有原来的myql的root的密码: 方法一:在mysql系统外,使用mysqladmin# mysqladmin -u root -p password " ...

  4. MySQL主主复制、主从复制

    意思: 主机A上有mysql1,主机B上有mysql2,mysql1新建库D,则mysql2也新建库D,mysql1原有库A.B.C,mysql2也原有库A.B.C,总之mysql1和mysql2一样 ...

  5. LOJ121 「离线可过」动态图连通性

    思路 动态图连通性的板子,可惜我不会在线算法 离线可以使用线段树分治,每个边按照存在的时间插入线段树的对应节点中,最后再dfs一下求出解即可,注意并查集按秩合并可以支持撤销操作 由于大量使用STL跑的 ...

  6. 文件IO(2)

    Lseek:       ***************************************************************************    实验一:     ...

  7. mysql分区分表讲解

    为什么要分表和分区? 日常开发中我们经常会遇到大表的情况,所谓的大表是指存储了百万级乃至千万级条记录的表.这样的表过于庞大,导致数据库在查询和插入的时候耗时太长,性能低下,如果涉及联合查询的情况,性能 ...

  8. HDU 5844 LCM Walk(数学逆推)

    http://acm.hdu.edu.cn/showproblem.php?pid=5584 题意: 现在有坐标(x,y),设它们的最小公倍数为k,接下来可以移动到(x+k,y)或者(x,y+k).现 ...

  9. _itemmod_extract_enchant

    comment 备注 entry 物品ID CanExtract 1 - 可提取随机FM 0 - 不可提取随机FM,当CanExtract = 1 且有随机FM效果时,随机FM效果会被提取 CanEn ...

  10. Unity Shaderlab: Object Outlines 转

    转 https://willweissman.wordpress.com/tutorials/shaders/unity-shaderlab-object-outlines/ Unity Shader ...