1.WAV文件结构解析
字节位置 | Sample Value | 描述 |
---|
1 – 4 | “RIFF” | 1–4“RIFF”将文件标记为RIFF文件。每个字符的长度为1字节。 |
5 – 8 | File size (integer) | 5–8文件大小(整数)整个文件的大小–8字节,以字节为单位(32位整数)。通常,您会在创建后填写此项。 |
45181 | “WAVE” | 9-12“WAVE”文件类型标题。就我们的目的而言,它总是等于“WAVE”。 |
13-16 | “fmt “ | 13-16“fmt”格式化区块标记。包括尾部null |
17-20 | 16 | 17-20 16上面列出的格式数据长度 |
21-22 | 1 | 21-22 1格式类型(1为PCM)–2字节整数 |
23-24 | 2 | 23-24 2通道数–2字节整数 |
25-28 | 44100 | 25-28 44100采样率–32字节整数。常见值为44100(CD)、48000(DAT)。采样率=每秒采样数,或赫兹。 |
29-32 | 176400 | 29-32 176400(采样率比特每采样通道)/8。 |
33-34 | 4 | 33-34 4(BitsPerSample*通道)/8.1–8位单声道2–8位立体声/16位单声道4–16位立体声 |
35-36 | 16 | 35-36每个样本16位 |
37-40 | “data” | 37-40“数据”“数据”块标头。标记数据节的开头。 |
41-44 | File size (data) | 41-44文件大小(数据)数据部分的大小。 |
WAV头结构体与转换方法
[StructLayout(LayoutKind.Sequential)]
public struct wavfile_header
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public char[] riff_tag=new char[] {'R','I','F','F' };
public uint riff_length=0;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public char[] wave_tag=new char[] { 'W','A','V','E'};
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public char[] fmt_tag=new char[] { 'f','m','t',' '};
public uint fmt_length=0;
public ushort audio_format=1;
public ushort num_channels=1;
public uint sample_rate=1;
public uint byte_rate = 1;
public ushort block_align = 1;
public ushort bits_per_sample = 1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public char[] data_tag=new char[] { 'd','a','t','a'};
public uint data_length = 1;
public wavfile_header()
{
}
}
public void PCMToWAV(ushort _channels, uint samplesPerSec, ushort _bitsPerSample,string PCMPath,string SavePath)
{
byte[] PCMdata=File.ReadAllBytes(PCMPath);
wavfile_header header = new wavfile_header();
header.riff_length = (uint)(36 + PCMdata.Length);
header.fmt_length = 16;
header.audio_format = 1;
header.num_channels = _channels;
header.sample_rate = samplesPerSec;
header.byte_rate = samplesPerSec * _channels * _bitsPerSample / 8 + _channels;
header.block_align = (ushort)(_channels * _bitsPerSample / 8);
header.bits_per_sample = _bitsPerSample;
header.data_length = (uint)PCMdata.Length;
byte[] headerbytes = StructToBytes(header);
FileStream fs=File.Create(SavePath);
fs.Write(headerbytes, 0, headerbytes.Length);
fs.Write(PCMdata, 0, PCMdata.Length);
fs.Close();
}