C#WAV音频文件转化PCM数据文件PCM转化WAV音频
2017-07-11 11:54
507 查看
源文件在下面连接
代码如下:
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); } //只读方式打开文件 4000 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"); } } }
资源下载:点我跳转
相关文章推荐
- 音频数据文件格式(PCM,WAV,MIDI)简记
- wave文件(*.wav)格式、PCM数据格式
- PCM数据合成WAV文件
- wav文件提取出pcm数据
- 使用C语言实现从一段pcm格式音频文件中截取一段数据
- wave文件(*.wav)格式、PCM数据格式, goldwave 可以播放pcm raw audio
- PCM音频文件(.wav)压缩成GSM6.10(.wav)
- wave文件(*.wav)格式、PCM数据格式
- pcm数据生成wav文件
- 嵌入式 wave文件(*.wav)格式、PCM数据格式收藏
- C#Winformd读取excel文件数据转化为DataTable
- 音频数据文件WAVE结构分析--Windows XP 启动.wav 文件头分析
- C#使用SoundPlayer播放WAV音频文件
- wave文件(*.wav)格式、PCM数据格式
- C#把DataSet内数据转化为Excel和Word文件的通用类
- 把音频数据保存 wav文件, save audio data to wav file
- PCM音频文件(.wav)压缩成ADPCM(.wav)
- C#实现Wav文件截取、淡入淡出处理(PCM 格式)
- C#实现DataSet内数据转化为Excel和Word文件的通用类完整实例
- visual studio 2010环境下在C#程序中嵌入、播放 wav音频文件 图文介绍