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



资源下载:点我跳转


  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1、Java实现wav音频文件换为pcm音频文件(AudioUtils.java) 2、Java实现播放pcm音频文件PCMPlay.java) WAVwav是一种无损的音频文件格式,WAV符合 PIFF(Resource Interchange File Format)规范。所有的WAV都有一个文件头,这个文件头音频流的编码参数。WAV音频流的编码没有硬性规定,除了PCM之外,还有几乎所有支持ACM规范的编码都可以为WAV音频流进行编码。 PCM:PCM(Pulse Code Modulation----脉码调制录音)。所谓PCM录音就是将声音等模拟信号变成符号化的脉冲列,再予以记录。PCM信号是由[1]、[0]等符号构成的数字信号,而未经过任何编码和压缩处理。与模拟信号比,它不易受传送系统的杂波及失真的影响。动态范围宽,可得到音质相当好的影响效果。 简单来说:wav是一种无损的音频文件格式,pcm是没有压缩的编码方式。 WAVPCM的关系 WAV可以使用多种音频编码来压缩其音频流,不过我们常见的都是音频流被PCM编码处理的WAV,但这不表示WAV只能使用PCM编码,MP3编码同样也可以运用在WAV中,和AVI一样,只要安装好了相应的Decode,就可以欣赏这些WAV了。在Windows平台下,基于PCM编码的WAV是被支持得最好的音频格式,所有音频软件都能完美支持,由于本身可以达到较高的音质的要求,因此,WAV也是音乐编辑创作的首选格式,适合保存音乐素材。因此,基于PCM编码的WAV被作为了一种中介的格式,常常使用在其他编码的相互换之中,例如MP3换成WMA。 简单来说:pcm是无损wav文件中音频数据的一种编码方式,但wav还可以用其它方式编码。
要在C#中生成wav音频文件的频谱图,可以使用Spectrogram库。这个库适用于.NET Standard,可以在.NET Framework和.NET Core项目中使用。它使用FFT算法和窗口函数来创建频谱图。 如果你遇到了困难,可以参考一些方法,但要注意确保方法的正确性。你可以在以下链接中找到一个源码示例:http://download.csdn.net/download/qq_40006363/10131910。 在代码中,你需要指定要换的wav文件的路径。例如,可以使用类似下面的代码来指定路径: string filePath = "d:/genres/g/converted/g." + n.ToString().PadLeft(5, '0') + ".au.wav"; 然后,你可以使用Spectrogram库加载音频文件并生成频谱图。具体的实现代码可能会有所不同,因为它取决于你使用的库和具体的需求。但是,你可以根据库的文档或示例进行操作。 请注意,生成频谱图需要一些音频处理的知识和算法,所以在使用库之前,最好对音频处理和信号处理有一定的了解。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Spectrogram:用于创建频谱图的 .NET 库](https://download.csdn.net/download/weixin_42168750/19225143)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [C# 实现wav 文件读取并绘制波形图](https://blog.csdn.net/qq_40006363/article/details/78655110)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [.wav音乐文件换为.fft.npy频谱格式文件](https://blog.csdn.net/qq_41264055/article/details/124591413)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_陈陆亮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值