WAV和PCM文件转换的程序
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文件转换的程序的更多相关文章
- WebRTC录音(2)-录音文件转换成WAV格式
以下是源码,大路货,从网上找的. 但是,这个东西在MacOS上是有问题的,原因在最后,都是泪啊. #include <stdio.h> #include <string.h> ...
- (原创)speex与wav格式音频文件的互相转换(二)
之前写过了如何将speex与wav格式的音频互相转换,如果没有看过的请看一下连接 http://www.cnblogs.com/dongweiq/p/4515186.html 虽然自己实现了相关的压缩 ...
- (原创)speex与wav格式音频文件的互相转换
我们的司信项目又有了新的需求,就是要做会议室.然而需求却很纠结,要继续按照原来发语音消息那样的形式来实现这个会议的功能,还要实现语音播放的计时,暂停,语音的拼接,还要绘制频谱图等等. 如果是wav,m ...
- ocx文件转换成C#程序引用的DLL
将ocx文件转换成C#程序引用的DLL文件的办法 将ocx文件转换成C#程序引用的DLL文件的办法,需要的朋友可以参考一下 1.打开VS2008或VS2010命令提示符(此例用VS2008) 将o ...
- 【数据预处理】TIMIT语料库WAV文件转换
1 问题描述 这两天复现代码.先构造数据集,纯净语音.不同噪声.不同SNR的混合语音.其中纯净语音由两部分组成,IEEE corpus和TIMIT. 一开始我用MATLAB中的audioread读取音 ...
- ffmpeg音频文件转换之使用stdin/stdout或BytesIO对象输入输出
最近在搞小程序录音,然后使用百度接口做语音识别. 小程序目前仅支持mp3和aac编码格式.虽然百度接口提供的m4a格式支持能直接识别小程序的录音文件,但由于自己还有其他一系列需求(比如直接读取数据,根 ...
- .net amr格式文件转换成mp3格式文件的方法
前言:winform端对于音频文件的格式多有限制,大多数不支持amr格式的文件的播放.但是,手机端传过来的音频文件大多数是amr格式的文件,所以,要想在winform客户端支持音频文件的播放,可以通过 ...
- WAV和PCM的关系和区别
什么是WAV和PCM? WAV:wav是一种无损的音频文件格式,WAV符合 PIFF(Resource Interchange File Format)规范.所有的WAV都有一个文件头,这个文件头音频 ...
- net 预览文件 转换文件
预览SWF文件 swfobject.js (google浏览器 会阻止 需设置) @{ ViewBag.Title = "PdfPreview"; Layout = " ...
随机推荐
- 求最大流dinic算法模板
//最短增广路,Dinic算法 struct Edge { int from,to,cap,flow; };//弧度 void AddEdge(int from,int to,int cap) //增 ...
- Spring Boot 项目中常见注解
@Autowired 自动导入依赖的 Bean.byType方式.把配置好的 Bean拿来用,完成属性.方法的组装,它可以对类成员变量.方法及构造函数进行标注,完成自动装配的工作 import org ...
- 浅谈Log4j2日志框架及使用
目录 1.日志框架 2.为什么需要日志接口,直接使用具体的实现不就行了吗? 3.log4j2日志级别 4.log4j2配置文件的优先级 5.对于log4j2配置文件的理解 6.对于Appender的理 ...
- 如何清除浮动塌陷? float:left 塌陷
参考文章: http://www.jb51.net/css/502268.html 原文链接:http://www.jianshu.com/p/a0500b54da13 只要给li的宽度, 规定得小一 ...
- .net Core 2.1 后 Session保存,新页面获取不到值
https://blog.csdn.net/kuui_chiu/article/details/81060051 https://blog.csdn.net/niunan/article/detail ...
- [AtCode 4104] Small and Large Integers
题目链接:https://abc093.contest.atcoder.jp/tasks/abc093_b?lang=en 这个题虽然很水,但是还是很容易踩坑,比如我,直接想到了[b,a]之间的长度和 ...
- IE7及以下浏览器不支持json的解决方法
在页面 alert(JSON);//大写 IE7及以下浏览器不支持json所以不会弹出object 解决方法打开json.org json的官网找到javascript的json2.js然后会转到gi ...
- 《机器学习实战》之k-近邻算法(示例)
看了这本书的第一个算法—k-近邻算法,这个算法总体构造思想是比较简单的,在ACM当中的话就对应了kd树这种结构.首先需要给定训练集,然后给出测试数据,求出训练集中与测试数据最相近的k个数据,根据这k个 ...
- JMeter 生成CSV文件中文变乱码的问题
在通过BeanShell 生成CSV文件时,写入的中文字符默认情况会变成乱码. //默认情况生成的文件是asii编码.fileName = “c:\test.csv";fos = new F ...
- Codeforces 746 G. New Roads
题目链接:http://codeforces.com/contest/746/problem/G mamaya,不知道YY了一个什么做法就这样过去了啊 2333 首先我显然可以随便构造出一棵树满足他所 ...