c# pcm
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[]; //header byte
private byte[] databuff; //data byte
public Form2()
{
InitializeComponent();
InitialStruct();
}
/// <summary>
/// 初始化结构体中的数组长度,分配内存
/// </summary>
private void InitialStruct()
{
wavHander.riff = new byte[];//RIFF
wavHander.wave = new byte[];//WAVE
wavHander.fmt = new byte[];//fmt
wavHander.data = new byte[];//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 + ];//分配 内存
file.Read(databuff, , 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 - ); /*语音数据的长度 4byte*/
byte[] byt2;//临时变量 ,保存2位的整数
byte[] byt4;//临时变量, 保存4位的整数
Encoding.ASCII.GetBytes(Encoding.ASCII.GetString(wavHander.riff), , , databuff, );/*RIFF类资源文件头部 4byte*/
byt4 = BitConverter.GetBytes(wavHander.file_len); /*文件长度4byte*/
Array.Copy(byt4, , databuff, , );
Encoding.ASCII.GetBytes(Encoding.ASCII.GetString(wavHander.wave), , , databuff, );/*"WAVE"标志4byte*/
Encoding.ASCII.GetBytes(Encoding.ASCII.GetString(wavHander.fmt), , , databuff, );/*"fmt"标志4byte*/
byt4 = BitConverter.GetBytes(wavHander.NI1);/*过渡字节4byte*/
Array.Copy(byt4, , databuff, , );
byt2 = BitConverter.GetBytes(wavHander.format_type);/*格式类别(10H为PCM形式的声音数据)2byte*/
Array.Copy(byt2, , databuff, , );
byt2 = BitConverter.GetBytes(wavHander.Channels);/*Channels 1 = 单声道; 2 = 立体声2byte*/
Array.Copy(byt2, , databuff, , );
byt4 = BitConverter.GetBytes(wavHander.frequency);/*采样频率4byte*/
Array.Copy(byt4, , databuff, , );
byt4 = BitConverter.GetBytes(wavHander.trans_speed);/*音频数据传送速率4byte*/
Array.Copy(byt4, , databuff, , );
byt2 = BitConverter.GetBytes(wavHander.dataBlock);/*数据块的调整数(按字节算的)2byte*/
Array.Copy(byt2, , databuff, , );
byt2 = BitConverter.GetBytes(wavHander.sample_bits);/*样本的数据位数(8/16) 2byte*/
Array.Copy(byt2, , databuff, , );
Encoding.ASCII.GetBytes(Encoding.ASCII.GetString(wavHander.data), , , databuff, );/*数据标记符"data" 4byte*/
byt4 = BitConverter.GetBytes(wavHander.wav_len); /*语音数据的长度 4byte*/
Array.Copy(byt4, , databuff, , );
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,或者打开失败
{
file.Close();//
throw new Exception(ERRFILEISNOTWAVE);
}
file.Read(buff, , );//读取文件头
if (fixedData(buff) == false)//按位置保存文件头信息到结构体中
throw new Exception(ERRFILEISNOTWAVE);
databuff = new byte[wavHander.wav_len];//分配内存
try
{
file.Read(databuff, , 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, , wavHander.riff, , );//
if (Encoding.ASCII.GetString(wavHander.riff) != "RIFF")//确定文件是WAVA类型
return false;
wavHander.file_len = BitConverter.ToUInt32(pbuff, );
Array.Copy(pbuff, , wavHander.wave, , );
Array.Copy(pbuff, , wavHander.fmt, , );
wavHander.NI1 = BitConverter.ToUInt32(pbuff, );
wavHander.format_type = BitConverter.ToUInt16(pbuff, );
wavHander.Channels = BitConverter.ToUInt16(pbuff, );
wavHander.frequency = BitConverter.ToUInt32(pbuff, );
wavHander.trans_speed = BitConverter.ToUInt32(pbuff, );
wavHander.dataBlock = BitConverter.ToUInt16(pbuff, );
wavHander.sample_bits = BitConverter.ToUInt16(pbuff, );
Array.Copy(pbuff, , wavHander.data, , );
wavHander.wav_len = BitConverter.ToUInt32(pbuff, );
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 = ;
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 = ;
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, , 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");
}
}
}
c# pcm的更多相关文章
- linux下mono播放PCM音频
测试环境: Ubuntu 14 MonoDevelop CodeBlocks 1.建立一个共享库(shared library) 这里用到了linux下的音频播放库,alsa-lib. al ...
- PCM数据格式,多少字节算一帧
转自:http://blog.chinaunix.net/uid-9185047-id-3327302.html Somehow i remember that normally 2048 sampl ...
- ffplay代码播放pcm数据
摘抄雷兄 http://blog.csdn.net/leixiaohua1020/article/details/46890259 /** * 最简单的SDL2播放音频的例子(SDL2播放PCM) * ...
- I2S/PCM/IOM-2、I2C/SPI/UART/GPIO/slimbus
概述 I2S,PCM,IOM-2都是数字音频接口,传数据的. I2C,SPI,UART,GPIO是控制接口,传控制信令的. I2S I2S(Inter-IC Sound Bus)是飞利浦公司为数字音频 ...
- PCM(Pulse-code modulation)脉冲编码调制
在音频处理中,我们会经常听到PCM数据,那么什么是PCM数据呢? PCM数据就是模拟信号经过PCM以后的数字信号,PCM就是把音频信号由模拟信号(时间连续,取值连续)转为数字信号(时间离散,取值离散) ...
- android pcm
Android.media package里包含声音录放的两个类AudioRecord和AudioTrack.前者用来录制,后者用来播放. 配置 pcm: int channel = AudioFor ...
- FM/PCM与FM/PPM的区别
FM/PCM的优点: 1 高可靠性和高抗干扰性.大家知道,一般PPM遥控设备都要求在操作时先开发射机后开接收机,先关接收机后关发射机.其原因是在没有发射信号时,接受机会因自身内部的噪音或外界的 ...
- 给pcm格式文件加wav文件头
#include <stdlib.h>#include <stdio.h>#include <string.h>void main(){ //wav头的结构如下所示 ...
- pcm跟.wav文件的关系
PCM(Pulse Code Modulation----脉码调制录音).所谓PCM录音就是将声音等模拟信号变成符号化的脉冲列,再予以记录.PCM信号是由[1].[0]等符号构成的数字信号,而未经过任 ...
- PCM音频设备的操作(转)
对音频设备的操作主要是初始化音频设备以及往音频设备发送 PCM(Pulse Code Modulation)数据.为了方便,本文使用 ALSA(Advanced Linux Sound Archite ...
随机推荐
- Linux - Shell - 算数表达式 - 位运算
概述 shell 中基于 $(()) 的 位运算 背景 复习 shell 脚本 凑数吧 准备 环境 os centos7 1. 位运算 代码 #!/bin/bash # 位运算 arg1=2 arg2 ...
- 【Python】random库
种子相同,随机数相同
- Redis Bitmap
Redis提供对字符串的按位操作,位图把字符串抽象成一个bool类型的数组,可以进行按位操作 比如说我有一个字符串“a” 那他的位图如下 (位) 7 6 5 4 3 2 1 0 (值) 0 1 0 ...
- 一看就会一做就废系列:说说 RECOVER DATABASE(下)
这里是:一看就会,一做就废系列 数据库演示版本为 19.3 (12.2.0.3) 该系列涉及恢复过程中使用的 个语句: 1. recover database 2. recover database ...
- Android SDK安装环境变量配置
安卓tool: http://tools.android-studio.org/ SDK下载地址:http://dl.google.com/android/android-sdk_r24.4.1-wi ...
- dict 字典合并
实例 1 : 使用 update() 方法,第二个参数合并第一个参数 def Merge(dict1, dict2): return(dict2.update(dict1)) 实例 2 : 使用 ...
- index unique scan 与index range scan等的区别
存取Oracle当中扫描数据的方法(一) Oracle 是一个面向Internet计算环境的数据库.它是在数据库领域一直处于领先地位的甲骨文公司的产品.可以说Oracle关系数据库系统是目前世界上流行 ...
- AcWing 907. 区间覆盖
//1.将所有区间按照左端点从小到大排序 //2.从前往后依次枚举每个区间 //首先选择能够覆盖左端点的区间当中右端点最靠右的端点 //在所有能覆盖start的区间当中,选择右端点最大的区间 //选完 ...
- Python - 安装 - 在 Alpine Linux 下安装 Python2
概述 在 Alpine Liunx 下安装 python2 感觉又是水了一发... 感觉还是有点丢人, 就像在帮小学生写作业, 写完了后还想找人夸我... 最近看 docker 和 jenkins, ...
- vue中style下scope的使用和坑
在vue组件中,为了使样式私有化(模块化),不对全局造成污染,可以在style标签上添加scoped属性以表示它的只属于当下的模块,这是一个非常好的举措,但是为什么要慎用呢?因为在我们需要修改公共组件 ...