WAVE文件头格式剖析以及pcm2wav

原创 2012年03月22日 15:25:57
常用语音编码的WAVE文件头格式剖析

  WAVE文件头作为多媒体中使用的声波文件格式之一,它是以RIFF格式为标准的。RIFF是英文Resource Interchange File Format的缩写,每个WAVE文件的头四个字节便是“RIFF”。合理利用WAVE文件头可以更有效地进行语音解码。

  通常意义上说的语音编码都是指将8KHz采样、16比特量化的线性PCM语音信号压缩成其它格式的语音信号,解码时就将其它格式的语音信号变换成8KHz采样、16比特量化的线性PCM语音信号。一般说来,这个转换过程比较复杂,费时费力。如果对其它格式的语音信号直接加上对应的WAVE文件头就不用这个转换过程,用微软自带的录音机就可解码语音。

 下面就分别剖析各种语音编码的WAVE文件头格式,用如下各个表(表1到表7)进行对比即可。


表1 8KHz采样、16比特量化的线性PCM语音信号的WAVE文件头格式表(共44字节)




偏移地址 字节数 数据类型 内容 文件头定义为
00H 4 char "RIFF" char riff_id[4]="RIFF"
04H 4 long int 文件总长-8 long int size0=文总长-8
08H 8 char "WAVEfmt " char wave_fmt[8]
10H 4 long int 10 00 00 00H(PCM) long int size1=0x10
14H 2 int 01 00H int fmttag=0x01
16H 2 int int channel=1 或2
18H 4 long int 采样率 long int samplespersec
1CH 4 long int 每秒播放字节数 long int bytepersec
20H 2 int 采样一次占字节数 int blockalign=声道数*量化数/8
22H 2 int 量化数 int bitpersamples=8或16
24H 4 char "data" char data_id="data"
28H 4 long int 采样数据字节数 long int size2=文长-44
2CH 到文尾 char 采样数据  




表2 8KHz采样、8比特A律量化的PCM语音信号的WAVE文件头格式表(共58字节)




偏移地址 字节数 数据类型 内容 文件头定义为
00H 4 char "RIFF" char riff_id[4]="RIFF"
04H 4 long int 文件总长-8 long int size0=文总长-8
08H 8 char "WAVEfmt " char wave_fmt[8]
10H 4 long int 12000000H(ALAW) long int size1=0x12
14H 2 int 06 00H int fmttag=0x06
16H 2 int 声道数 int channel=1 或2
18H 4 long int 采样率 long int samplespersec
1CH 4 long int 每秒播放字节数 long int bytepersec
20H 2 int 采样一次占字节数 int blockalign=0x01
22H 4 long int 量化数 long int bitpersamples=8
26H 4 char "fact" char wave_fact="fact"
2AH 8 char 0400000000530700H定 char temp
32H 4 char "data" char wave_data="data"
36H 4 long int 采样数据字节数 lont int size2=文长-58




表3 8KHz采样、8比特U律量化的PCM语音信号的WAVE文件头格式表(共58字节)




偏移地址 字节数 数据类型 内容 文件头定义为
00H 4 char "RIFF" char riff_id[4]="RIFF"
04H 4 long int 文件总长-8 long int size0=文总长-8
08H 8 char "WAVEfmt " char wave_fmt[8]
10H 4 long int 12000000H(ULAW) long int size1=0x12
14H 2 int 07 00H int fmttag=0x07
16H 2 int 声道数 int channel=1 或2
18H 4 long int 采样率 long int samplespersec
1CH 4 long int 每秒播放字节数 long int bytepersec
20H 2 int 采样一次占字节数 int blockalign=0x01
22H 4 long int 量化数 long int bitpersamples=8
26H 4 char "fact" char wave_fact="fact"
2AH 8 char 0400000000530700H定 char temp
32H 4 char "data" char wave_data="data"
36H 4 long int 采样数据字节数 lont int size2=文长-58




表4 ADPCM语音编码后的WAVE文件头格式表(共90字节)




偏移地址 字节数 数据类型 内容 文件头定义为
00H 4 char "RIFF" char riff_id[4]="RIFF"
04H 4 long int 文件总长-8 long int size0=文总长-8
08H 8 char "WAVEfmt " char wave_fmt[8]
10H 4 long int 32000000H(ADPCM) long int size1=0x32
14H 2 int 02 00H int fmttag=0x02
16H 2 int 声道数 int channel=1 或2
18H 4 long int 采样率 long int samplespersec
1CH 4 long int 每秒播放字节数 long int bytepersec
20H 2 int 采样一次占字节数 int blockalign=声道数*量化数/8
22H 2 int 量化数 int bitpersamples=4
24H 34 char 固定字节 char temp1
46H 4 char "fact" char wave_fact="fact"
4AH 8 char 0400000004930600H定 char temp2
52H 4 char "data" char wave_data="data"
56H 4 long int 采样数据字节数 lont int size2=文长-90
5AH 到文尾 采样数据    




表5 GSM语音编码后的WAVE文件头格式表(共60字节)




偏移地址 字节数 数据类型 内容 文件头定义为
00H 4 char "RIFF" char riff_id[4]="RIFF"
04H 4 long int 文件总长-8 long int size0=文总长-8
08H 8 char "WAVEfmt " char wave_fmt[8]
10H 4 long int 14000000H(GSM) long int size1=0x14
14H 2 int 31 00H int fmttag=0x31
16H 2 int 声道数 int channel=1 或2
18H 4 long int 采样率 long int samplespersec
1CH 4 long int 每秒播放字节数 long int bytepersec
20H 8 char 4100000002004001H定 char temp1
28H 8 char 6661637404000000H定 char temp2
30H 4 char 40 E2 05 00H定 char temp3
34H 4 char "data" char wave_data="data"
38H 4 long int 采样数据字节数 lont int size2=文长-60
3CH 到文尾 采样数据    




表6 SBC语音编码后的WAVE文件头格式表(共58字节)




偏移地址 字节数 数据类型 内容 文件头定义为
00H 4 char "RIFF" char riff_id[4]="RIFF"
04H 4 long int 文件总长-8 long int size0=文总长-8
08H 8 char "WAVEfmt " char wave_fmt[8]
10H 4 long int 12000000H(SBC) long int size1=0x12
14H 2 int 71 00H int fmttag=0x71
16H 2 int 声道数 int channel=1 或2
18H 4 long int 采样率 long int samplespersec
1CH 4 long int 每秒播放字节数 long int bytepersec
20H 2 int 采样一次占字节数 int blockalign=0x25
22H 4 long int 量化数 long int bitpersamples=16
26H 4 char "fact" char wave_fact="fact"
2AH 8 char 0400000076280400H定 char temp
32H 4 char "data" char wave_data="data"
36H 4 long int 采样数据字节数 lont int size2=文长-59




表7 CELP语音编码后的WAVE文件头格式表(共58字节)




偏移地址 字节数 数据类型 内容 文件头定义为
00H 4 char "RIFF" char riff_id[4]="RIFF"
04H 4 long int 文件总长-8 long int size0=文总长-8
08H 8 char "WAVEfmt " char wave_fmt[8]
10H 4 long int 12000000H(CELP) long int size1=0x12
14H 2 int 70 00H int fmttag=0x70
16H 2 int 声道数 int channel=1 或2
18H 4 long int 采样率 long int samplespersec
1CH 4 long int 每秒播放字节数 long int bytepersec
20H 2 int 采样一次占字节数 int blockalign=0x0C
22H 4 long int 量化数 long int bitpersamples=16
26H 4 char "fact" char wave_fact="fact"
2AH 8 char 0400000060520700H定 char temp
32H 4 char "data" char wave_data="data"

36H 4 long int 采样数据字节数 lont int size2=文长-58


// Test.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include <windows.h>
#include <string>
using namespace std;

struct tagHXD_WAVFLIEHEAD
{
	CHAR RIFFNAME[4];
	DWORD nRIFFLength;
	CHAR WAVNAME[4];
	CHAR FMTNAME[4];
	DWORD nFMTLength;
	WORD nAudioFormat;

	WORD nChannleNumber;
	DWORD nSampleRate;
	DWORD nBytesPerSecond;
	WORD nBytesPerSample;
	WORD    nBitsPerSample;
	CHAR    DATANAME[4];
	DWORD   nDataLength;
};typedef tagHXD_WAVFLIEHEAD HXD_WAVFLIEHEAD;

int a_law_pcm_to_wav(const char *pcm_file, const char *wav)
{
	// 开始准备WAV的文件头
	HXD_WAVFLIEHEAD DestionFileHeader;
	DestionFileHeader.RIFFNAME[0] = 'R';
	DestionFileHeader.RIFFNAME[1] = 'I';
	DestionFileHeader.RIFFNAME[2] = 'F';
	DestionFileHeader.RIFFNAME[3] = 'F';

	DestionFileHeader.WAVNAME[0] = 'W';
	DestionFileHeader.WAVNAME[1] = 'A';
	DestionFileHeader.WAVNAME[2] = 'V';
	DestionFileHeader.WAVNAME[3] = 'E';

	DestionFileHeader.FMTNAME[0] = 'f';
	DestionFileHeader.FMTNAME[1] = 'm';
	DestionFileHeader.FMTNAME[2] = 't';
	DestionFileHeader.FMTNAME[3] = 0x20;
	DestionFileHeader.nFMTLength = 16;  //  表示 FMT 的长度
	DestionFileHeader.nAudioFormat = 6; //这个表示a law PCM

	DestionFileHeader.DATANAME[0] = 'd';
	DestionFileHeader.DATANAME[1] = 'a';
	DestionFileHeader.DATANAME[2] = 't';
	DestionFileHeader.DATANAME[3] = 'a';
	DestionFileHeader.nBitsPerSample = 8;
	DestionFileHeader.nBytesPerSample = 1;    //
	DestionFileHeader.nSampleRate = 8000;    //
	DestionFileHeader.nBytesPerSecond = 8000;
	DestionFileHeader.nChannleNumber = 1;

	// 文件头的基本部分
	int nFileLen = 0;
	int nSize = sizeof(DestionFileHeader);

	FILE *fp_s = NULL;
	FILE *fp_d = NULL;

	fp_s = fopen(pcm_file, "rb");
	if (fp_s == NULL)
		return -1;

	fp_d = fopen(wav, "wb+");
	if (fp_d == NULL)
		return -2;


	int nWrite = fwrite(&DestionFileHeader, 1, nSize, fp_d);     //将文件头写入wav文件
	if (nWrite != nSize)
	{
		fclose(fp_s);
		fclose(fp_d);
		return -3;
	}

	while( !feof(fp_s))
	{
		char readBuf[4096];
		int nRead = fread(readBuf, 1, 4096, fp_s);    //将pcm文件读到readBuf
		if (nRead > 0)
		{
			fwrite(readBuf, 1, nRead, fp_d);      //将readBuf文件的数据写到wav文件
		}

		nFileLen += nRead;
	}
	fseek(fp_d, 0L, SEEK_SET);   //将读写位置移动到文件开头

	DestionFileHeader.nRIFFLength = nFileLen - 8 + nSize;
	DestionFileHeader.nDataLength = nFileLen;
	nWrite = fwrite(&DestionFileHeader, 1, nSize, fp_d);   //重新将文件头写入到wav文件
	if (nWrite != nSize)
	{
		fclose(fp_s);
		fclose(fp_d);
		return -4;
	}

	fclose(fp_s);
	fclose(fp_d);

	return nFileLen;
}


int _tmain(int argc, _TCHAR* argv[])
{

	char pcm[256]={0},wav[256]={0};
	strcpy(pcm,"C:\\2200124.pcm");
	strcpy(wav,"C:\\2200124.wav");
	a_law_pcm_to_wav(pcm,wav);

  
   getchar();
	return 0;
}


PCM音频文件格式的头信息

一个裸的PCM格式音频数据,如果不带头信息,不知道其采样率等相关信息,就无法用播放器播放出来。下面是默认的头信息格式://音频头部格式 struct wave_pcm_hdr { char ...

关于pcm音频头与a-law音频头的互换代码

在一个项目中有一个关于不同音频播放的问题,需要进行转换。今天突然要用到找了好久,觉得该代码蛮有意义的,记录下以免下次想用找不到。 /**********************************...
  • fjhyy
  • fjhyy
  • 2011年07月08日 16:14
  • 5691

WAVE文件的头格式(例如PCM文件)

转自http://blog.csdn.net/ao929929fei/article/details/6164210 1、PCM和WAV WAV可以使用多种音频编码来压缩其音频流,不过...

wave文件(*.wav)格式、PCM数据格式

1. 音频简介   经常见到这样的描述: 44100HZ 16bit stereo 或者 22050HZ 8bit mono 等等. 44100HZ 16bit stereo: 每秒...

wave文件(*.wav)格式、PCM数据格式

 1. 音频简介 经常见到这样的描述: 44100HZ 16bit stereo 或者 22050HZ 8bit mono 等等.44100HZ 16bit stereo: 每秒钟有 44100 次采...

嵌入式 wave文件(*.wav)格式、PCM数据格式收藏

1. 音频简介   经常见到这样的描述: 44100HZ 16bit stereo 或者 22050HZ 8bit mono 等等. 44100HZ 16bit stereo: 每秒钟有 441...
  • skdkjxy
  • skdkjxy
  • 2013年12月02日 14:56
  • 966

wave文件(*.wav)格式、PCM数据格式

1. 音频简介 经常见到这样的描述: 44100HZ 16bit stereo 或者 22050HZ 8bit mono 等等. 44100HZ 16bit stereo: 每秒钟有 44...

音频编解码·格式篇(1)Wave PCM audio format(WAV)

音频编解码·格式篇(1)Wave PCM audio format(WAV)作者:柳大·Poechant博客:Blog.CSDN.net/Poechant邮箱:zhongchao.ustc@gmail...
  • Poechant
  • Poechant
  • 2012年04月08日 01:40
  • 28020

音频编解码·格式篇(1)Wave PCM audio format(WAV)

作者:柳大·Poechant博客:Blog.CSDN.net/Poechant邮箱:zhongchao.ustc@gmail.com日期:April 6th, 2012 0 音频编解码基础 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:WAVE文件头格式剖析以及pcm2wav
举报原因:
原因补充:

(最多只允许输入30个字)