- 浏览: 1501830 次
- 性别:
- 来自: 南京
文章分类
- 全部博客 (419)
- XMPP (19)
- Android (180)
- Java (59)
- Network (4)
- HTML5 (13)
- Eclipse (9)
- SCM (23)
- C/C++ (4)
- UML (4)
- Libjingle (15)
- Tools&Softwares (29)
- Linphone (5)
- Linux&UNIX (6)
- Windows (18)
- Google (10)
- MISC (3)
- SIP (6)
- SQLite (5)
- Security (4)
- Opensource (29)
- Online (2)
- 文章 (3)
- MemoryLeak (10)
- Decompile (5)
- Ruby (1)
- Image (1)
- Bat (4)
- TTS&ASR (28)
- Multimedia (1)
- iOS (20)
- Asciiflow - ASCII Flow Diagram Tool.htm (1)
- Networking (1)
- DLNA&UPnP (2)
- Chrome (2)
- CI (1)
- SmartHome (0)
- CloudComputing (1)
- NodeJS (3)
- MachineLearning (2)
最新评论
-
bzhao:
点赞123!
Windows的adb shell中使用vi不乱码方法及AdbPutty -
wahahachuang8:
我觉得这种东西自己开发太麻烦了,就别自己捣鼓了,找个第三方,方 ...
HTML5 WebSocket 技术介绍 -
obehavior:
view.setOnTouchListenerview是什么
[转]android 一直在最前面的浮动窗口效果 -
wutenghua:
[转]android 一直在最前面的浮动窗口效果 -
zee3.lin:
Sorry~~
When I build "call ...
Step by Step about How to Build libjingle 0.4
参考网址一:http://blog.csdn.net/sshcx/archive/2007/05/01/1593923.aspx
参考网址二:http://apps.hi.baidu.com/share/detail/15909594
WAVE 文件作为多媒体中使用的声波文件格式之一,它是以RIFF格式为标准的。RIFF是英
文Resource Interchange File Format的缩写,每个WAVE文件的头四个字节便是"RIFF"。WAVE
文件由文件头和数据体两大部分组成。其中文件头又分为RIFF/WAV文件 标识段和声音数据格
式说明段两部分。
常见的声音文件主要有两种,分别对应于单声道(11.025KHz 采样率、8Bit的采样值)和
双声道(44.1KHz采样率、16Bit的采样值)。采样率是指:声音信号在"模→数"转换过程中单
位时间内采样的次数。 采样值是指每一次采样周期内声音模拟信号的积分值。
[!21ki@][@21ki!]
对于单声道声音文件,采样数据为八位的短整数(short int 00H-FFH);而对于双声道立体声
声音文件,每次采样数据为一个16位的整数(int),高八位和低八位分别代表左右两个声道。
WAVE文件数据块包含以脉冲编码调制(PCM)格式表示的样本。WAVE文件是由样本组织而成
的。在单声道WAVE文件中,声道0代表左声道,声道1代表右声道。在多声道WAVE文件中,样本
是交替出现的。
参考网址一和二中都给出了wav的头定义,但有一个小区别,一中将这个44个字节作为一个
大的头,给定在一个结构体中,而二中则是按照四个不同的chunk处理的,所以就给了四个结构
体,后面我的代码也是根据二来写的,个人觉得这样比较清晰,不过这纯属个人感觉。
下面就是根据四个结构体写的代码,注意FACT不是必须的,可以不用写入头,不写的话就
是44个字节,写的话wave的头是56个字节。
一:源代码(参考二中也有比较详细的读wave头的代码)
#if !defined(_WAV_INFO_)
#define _WAV_INFO_
// 一些和声音数据相关的宏
#define SAMPLE_RATE 22050 // sample rate,每秒22050个采样点
#define QUANTIZATION 0x10 // 16bit量化,
#define BYTES_EACH_SAMPLE 0x2 // QUANTIZATION / 8, 所以每个采样点、
// 是short,占个2个字节
#define CHANNEL_NUN 0x1 // 单声道
#define FORMAT_TAG 0x1 // 线性PCM
// 一个wave file包括四个CHUNK,除了FACT之外,其它是必须的,并且第一个RIFF是整个文件的头,
// 所以别名为WAV_HEADER,而不是RIFF
/*------------------------Wave File Structure ------------------------------------ */
typedef struct RIFF_CHUNK{
char fccID[4]; // must be "RIFF"
unsigned long dwSize; // all bytes of the wave file subtracting 8,
// which is the size of fccID and dwSize
char fccType[4]; // must be "WAVE"
}WAVE_HEADER;
// 12 bytes
typedef struct FORMAT_CHUNK{
char fccID[4]; // must be "fmt "
unsigned long dwSize; // size of this struct, subtracting 8, which
// is the sizeof fccID and dwSize
unsigned short wFormatTag; // one of these: 1: linear,6: a law,7:u-law
unsigned short wChannels; // channel number
unsigned long dwSamplesPerSec; // sampling rate
unsigned long dwAvgBytesPerSec; // bytes number per second
unsigned short wBlockAlign; // 每样本的数据位数(按字节算), 其值为:通道
// 数*每样本的数据位值/8,播放软件需要一次处
// 理多个该值大小的字节数据, 以便将其值用于
// 缓冲区的调整每样本占几个字节:
// NumChannels * uiBitsPerSample/8
unsigned short uiBitsPerSample; // quantization
}FORMAT;
// 24 bytes
// The fact chunk is required for all new WAVE formats.
// and is not required for the standard WAVE_FORMAT_PCM files
// 也就是说,这个结构体目前不是必须的,一般当wav文件由某些软件转化而成,则包含该Chunk
// 但如果这里写了,则必须是如下的结构,并且在四个结构体中的位置也要放在第三
typedef struct {
char fccID[4]; // must be "fact"
unsigned long id; // must be 0x4
unsigned long dwSize; // 暂时没发现有啥用
}FACT;
// 12 bytes
// 数据结构
typedef struct {
char fccID[4]; // must be "data"
unsigned long dwSize; // byte_number of PCM data in byte
}DATA;
// 8 bytes
/*------------------------Wave File Structure ------------------------------------ */
void WriteWaveHeader(FILE *fpwav,long length)
{
WAVE_HEADER WaveHeader;
FORMAT WaveFMT;
DATA WaveData;
FACT WaveFact;
memset(&WaveHeader, 0, sizeof(WAVE_HEADER));
memcpy(WaveHeader.fccID, "RIFF", 4);
memcpy(WaveHeader.fccType, "WAVE", 4);
// dwSize 是整个wave文件的大小(字节数,但不包括不包括HEADER中的前面两个结构:
// HEADER.fccID和HEAD.dwSize)
// WaveHeader.dwSize = length + 0x24; // 如果不写入fact,就是36个字节,
// 44- 8 = 36个
WaveHeader.dwSize = length + 0x30; // 如果写入fact,就是48 个bytes
memset(&WaveFMT, 0, sizeof(FORMAT));
memcpy(WaveFMT.fccID, "fmt ", 4);
WaveFMT.dwSize = 0x10;
WaveFMT.dwSamplesPerSec = SAMPLE_RATE;
WaveFMT.dwAvgBytesPerSec = CHANNEL_NUN * SAMPLE_RATE * BYTES_EACH_SAMPLE;
WaveFMT.wChannels = CHANNEL_NUN;
WaveFMT.uiBitsPerSample = QUANTIZATION;
WaveFMT.wFormatTag = FORMAT_TAG;
WaveFMT.wBlockAlign = BYTES_EACH_SAMPLE;
memset(&WaveFact, 0, sizeof(FACT));
memcpy(WaveFact.fccID, "fact", 4);
WaveFact.dwSize = length; // 这个值不知道什么意思
WaveFact.id = 0x4;
memset(&WaveData, 0, sizeof(DATA));
memcpy(WaveData.fccID, "data", 4);
WaveData.dwSize = length;
fwrite(&WaveHeader, sizeof(WAVE_HEADER), 1, fpwav);
fwrite(&WaveFMT, sizeof(FORMAT), 1, fpwav);
fwrite(&WaveFact, sizeof(FACT), 1, fpwav); // fact不是必须的
fwrite(&WaveData, sizeof(DATA), 1, fpwav);
}
void WriteWavfile(FILE *fp, short *pSpeechData, int length)
{
//write the header of wav
WriteWaveHeader(fp, length * BYTES_EACH_SAMPLE);
//write the data
fwrite(pSpeechData, sizeof(short), length, fp);
}
#endif
二:数据存储结构:
根据声音文件的声道和量化数的不同,在头之后的数据存储有不同的格式,如下面:
http://apps.hi.baidu.com/share/detail/15909594
---------------------------------------------------------------------
| 单声道 | 取样1 | 取样2 | 取样3 | 取样4 |
| | --------------------------------------------------------
| 8bit 量化 | 声道0 | 声道0 | 声道0 | 声道0 |
---------------------------------------------------------------------
| 双声道 | 取样1 | 取样2 |
| |--------------------------------------------------------
| 8bit 量化 | 声道0(左) | 声道1(右) | 声道0(左) | 声道1(右) |
---------------------------------------------------------------------
| | 取样1 | 取样2 |
| 单声道 |--------------------------------------------------------
| 16bit 量化 | 声道0 | 声道0 | 声道0 | 声道0 |
| | (低位字节) | (高位字节) | (低位字节) | (高位字节) |
---------------------------------------------------------------------
| | 取样1 |
| 双声道 |--------------------------------------------------------
| 16bit 量化 | 声道0(左) | 声道0(左) | 声道1(右) | 声道1(右) |
| | (低位字节) | (高位字节) | (低位字节) | (高位字节) |
---------------------------------------------------------------------
图:Wav 的data 数据的bit 位置可能的几种形式
三:各种头示例
常用语音编码的WAVE 文件头格式剖析--各种编码
http://www.360doc.com/content/10/0812/10/722458_45443101.shtml
表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
定 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
节数 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
WAVEFORMATEX
typedef struct{WORD wFormatTag; WORD nChannels; DWORD nSamplesPerSec; DWORD
nAvgBytesPerSec; WORD nBlockAlign; WORD wBitsPerSample; WORD cbSize; }
WAVEFORMATEX;
具体参数解释如下:
wFormatTag:波形数据的格式,定义在MMREG.H 文件中
nChannels:波形数据的通道数:单声道或立体声
nSamplesPerSec:采样率,对于PCM 格式的波形数据,采样率有8.0 kHz,11.025kHz,22.05 kHz,44.1
kHz 等
nAvgBytesPerSec:数据率,对于PCM 格式的波形数据,数据率等于采样率乘以每样点字节数
nBlockAlign:每个样点字节数
wBitsPerSample:采样精度,对于PCM 格式的波形数据,采样精度为8 或16
cbSize:附加格式信息的数据块大小
概念2、定义设备头结构
WAVEHDR 定义了指向波形数据缓冲区的设备头。
WAVEHDR
typedef struct { LPSTR lpData; DWORD dwBufferLength; DWORD dwBytesRecorded;
DWORD dwUser; DWORD dwFlags; DWORD dwLoops; struct wavehdr_tag * lpNext;
DWORD reserved; } WAVEHDR;
lpData:波形数据的缓冲区地址
dwBufferLength:波形数据的缓冲区地址的长度
dwBytesRecorded:当设备用于录音时,标志已经录入的数据长度
dwUser:用户数据
dwFlags:波形数据的缓冲区的属性
dwLoops:播放循环的次数,仅用于播放控制中
lpNext 和reserved 均为保留值
注意:上述结构体以及我们在程序中所使用到的“HWAVEIN””HWAVEOUT”结构体均是系统已
经存在的,我们只需要对其进行赋值即可。
- 详解wave头格式_尽可能详细并附代码_.pdf (188.1 KB)
- 下载次数: 21
发表评论
-
Voice detection for Android
2012-07-23 11:39 2341Here it is, my fist JAVA applic ... -
Google hired one of Nuance soft engineers to help work around all Nuance patents
2012-07-10 14:33 1096很有趣的消息: http://forums.macrumor ... -
The Voice Browser Working Group
2012-07-04 14:38 1975http://www.w3.org/Voice/ ... -
Nuance网站
2012-07-04 14:19 1299http://www.nuance.com/ http: ... -
Nuance HTTP Services
2012-07-03 13:57 977http://dragonmobile.nuancemobil ... -
Nuance - Dragon Mobile SDK - Speech Kit Library Guide (for Android)
2012-07-03 13:09 6507Speech Kit Library Gu ... -
Nuance - Dragon Mobile SDK - Speech Kit
2012-07-02 15:57 1413http://dragonmobile.nuancemobil ... -
Nuance’s Dragon ID Lets You Unlock Your Smartphone Or Tablet By Talking To It
2012-07-02 11:22 1144http://techcrunch.com/2012/06/0 ... -
Android 4.1 Jelly Bean adds Offline Voice Typing
2012-06-28 14:38 1407Google has added offline vo ... -
The http request header of Vlingo request
2012-05-22 21:48 1172Cache-Control no-cache,no-store ... -
三星已经禁止运行在其他手机上的S Voice应用访问服务器了
2012-05-22 09:45 1271S Voice刚被破解不久,三星就采取行动,禁止运行在其他手机 ... -
三星的S Voice应用
2012-05-21 14:58 1086三星的S Voice应用原来不是自己的技术,应该一点自己的技术 ... -
Samsung S Voice
2012-05-21 12:52 991三星Galaxy S III的S Voice应用已经被提取出来 ... -
The response from Vlingo
2012-05-14 16:53 1026<?xml version="1.0" ... -
TrulyHandsfree™ - The Important First Step in a Voice User Interface
2012-04-14 18:16 1157http://sensoryinc.com/blog/?p=4 ... -
eyes-free - Speech Enabled Eyes-Free Android Applications
2012-04-06 14:01 1121http://code.google.com/p/eyes-f ... -
Biometric Identification (生物特征识别)
2012-03-27 14:58 1253What is Biometric Identificat ... -
关于数字音频处理的一些常识
2012-03-23 10:25 1308数字音频处理技术http://apps.hi.baidu.co ... -
[AndroidTips]调用TextToSpeech朗读的时候如何中间停顿
2012-03-21 23:27 2844TTS在句子中间会停顿,你也可以通过在任何字符串中加点&quo ... -
The speech energy endpointer implementation from Chrome
2012-03-14 19:26 1159http://src.chromium.org/svn/tru ...
相关推荐
标题中的“加Wave文件头”指的是在音频处理中,为RAW格式的音频数据添加符合Wave文件格式规范的头部信息。Wave(WAV)是Microsoft公司开发的一种声音文件格式,广泛用于存储数字音频数据。它基于RIFF(Resource ...
2024版遗传算法详解 附python代码实现2024版遗传算法详解 附python代码实现2024版遗传算法详解 附python代码实现2024版遗传算法详解 附python代码实现2024版遗传算法详解 附python代码实现2024版遗传算法详解 附...
3ds文件格式详解: 3ds文件是Autodesk 3D Studio Max软件生成的一种三维模型文件格式,它被广泛用于游戏开发、视觉效果和动画制作等领域。这种格式支持基本的3D对象,如几何体、材质、纹理、灯光和相机设置等。在...
3. **驱动代码详解**: - `driver_lcd.c`:这是LCD驱动的核心代码,包含了初始化函数、数据写入函数、命令发送函数等。初始化通常包括设置GPIO模式、时钟配置、LCD控制器配置等;数据写入函数负责将要显示的数据...
以下是对Fortran语言的基本介绍、常用指令详解以及开发资源项目的详细介绍。 一、Fortran语言基本介绍 Fortran(FORmula TRANslation)是一种编译型语言,设计之初是为了解决科学计算中的数值问题。随着版本的更新...
**Wave文件格式详解** Wave(通常写作WAV)文件是一种由微软和IBM共同开发的音频文件格式,全称为“Waveform Audio Format”。它是未压缩的音频文件格式,以PCM(脉冲编码调制)或其他编码方式存储声音数据,提供高...
10大经典算法matlab代码以及代码详解10大经典算法matlab代码以及代码详解10大经典算法matlab代码以及代码详解10大经典算法matlab代码以及代码详解10大经典算法matlab代码以及代码详解10大经典算法matlab代码以及代码...
二、常用指令详解 变量声明 Kotlin 中有两种变量类型:val(不可变)和 var(可变)。 // 声明一个不可变的变量 val myName: String = "Alice" // 声明一个可变的变量 var count: Int = 0 count = 1 // 修改变量值...
区块链原理详解附代码.pptx
本部分首先将详细说明EtherCAT技术的基本特性,然后讨论基于ET9300的EtherCAT从站协议栈代码,并在结束部分提供应用示例和使用说明。 ### EtherCAT技术特点 EtherCAT是一种开放式以太网通讯协议,它允许在工业自动...
Python金融大数据挖掘与分析全流程详解-学习笔记及案例代码.zip Python金融大数据挖掘与分析全流程详解-学习笔记及案例代码.zip Python金融大数据挖掘与分析全流程详解-学习笔记及案例代码.zip Python金融大数据挖掘...
基于Python金融大数据挖掘与分析全流程详解案例代码.zip基于Python金融大数据挖掘与分析全流程详解案例代码.zip基于Python金融大数据挖掘与分析全流程详解案例代码.zip基于Python金融大数据挖掘与分析全流程详解案例...
拉格朗日插值法MATLAB实现(附代码、实例、详解)拉格朗日插值法MATLAB实现(附代码、实例、详解)拉格朗日插值法MATLAB实现(附代码、实例、详解)
区块链原理详解附代码PPT学习教案.pptx
### WAV文件格式详解 #### 一、概述 WAV(Waveform Audio File Format)是一种音频文件格式,由微软和IBM联合开发,遵循RIFF(Resource Interchange File Format)规范。这种格式广泛应用于Windows平台及其应用...
对String创建几个对象代码详解,包括字符串相加,对象相加等等
文件包括: 3ds Format.doc 3DS读取研究.doc 从3DS文件中导入网格数据.doc 源码: 一个完善的读取3DS文件例子.rar 3DS+File+Loader.rar 一款3D Max插件,导出.X文件PandaDirectXMaxExporter.rar
PLT文件格式详解.doc
### 粒子群算法详解 #### 一、粒子群算法概述 粒子群算法(Particle Swarm Optimization, PSO)是一种基于群体智能的优化算法,由Eberhart和Kennedy于1995年首次提出。它模拟了一群鸟或者鱼等生物群体在觅食过程中...