Wave Driver介绍
来源:互联网 发布:零度网络 下载空间 编辑:程序博客网 时间:2024/05/23 16:54
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
现在工作任务太杂了,从后台到数据库,再到界面,现在还要用音频相关的。
虽然是工作也要认真记录完成。
1 WAV/WMA/MP3的比较
介绍WAV格式之前,有必要拿最常见的几种格式进行一下比较。
MP3(Moving Picture Experts Group Audio Layer II)即MPEG Audio Layer3,是一种音频压缩技术。WMA诞生时间稍微晚一点,也是一种音频压缩技术,相关资料显示,其压缩率相对于MP3更有优势,只不过其标准不及MP3开放,所以市面上MP3格式的文件相对流行一些。
而WAV为声音文件的格式,采用RIFF标准(RIFF是Microsoft提出的一种多媒体文件的存储方式,不同编码的音频、视频文件,可以按照它定义的存储规则保存、记录各自不同的数据,WAV和AVI都采用这种标准),不进行压缩。
2 WAV格式描述
WAV格式符合RIFF标准,同样采用FOURCC,CHUNK和LIST进行组织,三者的关系形象的来进行比喻的话,FOURCC类似与Linux中的RootFS,LIST类似于各个分区的目录,而CHUNK类似于文件,系统中可能存在多个FOURCC和CHUNK,并且RIFF和LIST块可以包含其他块,而其它块仅能含有数据。
这里引用资料中的一张图片来进行形象说明,如下:
(待添加)
WAV文件由若干个Chunk构成,按照从前向后的顺序依次为RIFF WAVE CHUNKàFORMAT CHUNKàFACT CHUNK(可选,不一定有)àDATA CHUNK,如下图所示:
------------------------------------------------
| RIFF WAVE Chunk |
| ID = 'RIFF' |
| RiffType = 'WAVE' |
------------------------------------------------
| Format Chunk |
| ID = 'fmt ' |
------------------------------------------------
| Fact Chunk(optional) |
| ID = 'fact' |
------------------------------------------------
| Data Chunk |
| ID = 'data' |
------------------------------------------------
其中,按照RIFF的规定,每个Chunk的格式都是固定的,可以用下面的结构体来进行描述:
structchunk
{
u32id; /* 块标志*/
u32size; /* 块大小*/
u8dat[size]; /* 块内容*/
};
WAV文件的详细Layout如下表所描述:
endian
field name
Size
Column1
big
ChunkID
4
文件头标识,一般就是" RIFF" 四个字母
little
ChunkSize
4
整个数据文件的大小,不包括上面ID和Size本身
big
Format
4
一般就是" WAVE" 四个字母
big
SubChunk1ID
4
格式说明块,本字段一般就是"fmt "
little
SubChunk1Size
4
本数据块的大小,不包括ID和Size字段本身
little
AudioFormat
2
音频的格式说明
little
NumChannels
2
声道数
little
SampleRate
4
采样率
little
ByteRate
4
比特率,每秒所需要的字节数
little
BlockAlign
2
数据块对齐单元
little
BitsPerSample
2
采样时模数转换的分辨率
big
SubChunk2ID
4
真正的声音数据块,本字段一般是"data"
little
SubChunk2Size
4
本数据块的大小,不包括ID和Size字段本身
little
Data
N
音频的采样数据
举例以文件simtkit_callwait.wav为例来进一步说明wav文件的格式,该文件为WinCE6.0下的系统自带音频文件,可以从VS2005开发环境下找到。
该文件前64字节如下:
详细分析如下:
使用Adobe Audition分析如下:
分析Sample 0如下:
可以看到,采样点0的采样值(114)正好是二进制文件中Sample 0的采样值(0x72),其它采样点不再具体分析。
解析wav头文件代码如下:
struct RIFF_HEADER
{
char szRiffID[4]; // 'R','I','F','F'
DWORD dwRiffSize;
char szRiffFormat[4]; // 'W','A','V','E'
};
struct WAVE_FORMAT
{
WORD wFormatTag;
WORD wChannels;
DWORD dwSamplesPerSec;
DWORD dwAvgBytesPerSec;
WORD wBlockAlign;
WORD wBitsPerSample;
};
struct waveHead
{
RIFF_HEADER riff;
char szFmtID[4]; // 'f','m','t',' '
DWORD dwFmtSize;
WAVE_FORMAT wavFormat;
};
struct FACT_BLOCK
{
char szFactID[4]; // 'f','a','c','t'
DWORD dwFactSize;
};
struct DATA_BLOCK
{
char szDataID[4]; // 'd','a','t','a'
DWORD dwDataSize;
};
waveHead aHeader;
fseek(m_soundf, 0, SEEK_SET);
fread(&aHeader, 1, sizeof(waveHead), m_soundf);
memcpy(&m_wformat, &(aHeader.wavFormat), sizeof(WAVE_FORMAT));
m_wformat.cbSize = 0;
//if (aHeader.dwFmtSize == 18)
//fread(&(m_wformat.cbSize), 1, sizeof(WORD), m_soundf);
fseek(m_soundf, aHeader.dwFmtSize-16, SEEK_CUR);
FACT_BLOCK fact;
DATA_BLOCK data;
fread(&fact, 1, sizeof(FACT_BLOCK), m_soundf);
if (*((DWORD*)fact.szFactID) == *((DWORD*)"fact"))
{
fseek(m_soundf, fact.dwFactSize, SEEK_CUR);
fread(&data, 1, sizeof(DATA_BLOCK), m_soundf);
}
else if (*((DWORD*)fact.szFactID) == *((DWORD*)"data"))
memcpy(&data, &fact, sizeof(DATA_BLOCK));
m_iDataStart = ftell(m_soundf);
m_iDataSize = data.dwDataSize;
- Wave Driver介绍
- Wave Driver介绍-4(Wave API waveOutOpen)
- Wave Driver介绍-3(Wave API waveOutSetVolume)
- Wave Driver介绍-3(Wave API waveOutSetVolume)
- Wave Driver介绍-1(PCM文件格式)
- Wave Driver介绍-2(WAV文件格式)
- Wave Driver介绍-8(软件混音器)
- Wave Driver介绍-1(PCM文件格式)
- Wave Driver介绍-2(WAV文件格式)
- Wave Driver介绍-8(软件混音器)
- Wave Driver介绍-5(Waveform Audio Driver Test测试Case描述)
- Wave Driver介绍-5(Waveform Audio Driver Test测试Case描述)
- Wave Driver介绍-6(控制面板中的音量调整工具)
- Wave Driver介绍-7(驱动中对音量的控制操作-非硬件音量控制)
- Wave Driver介绍-6(控制面板中的音量调整工具)
- Wave Driver介绍-7(驱动中对音量的控制操作-非硬件音量控制)
- wave函数介绍
- wave函数介绍
- 【ci框架】ci框架mysql数据库连接资源无法释放
- Shell中脚本变量和函数变量的作用域
- 分享js中常用的方法 (好多土方法啊。。灰色背景慎用)
- 什么是aidl?Android AIDL详解
- MFC中利用ODBC连接MySql方法总结
- Wave Driver介绍
- 印度军官:中国取消阅舰式和美国拒绝参加有关
- PHP不是识别OneThink的验证码-解决方案
- iOS开发中,应用内直接跳转到Appstore
- webkit内核下(chrome 360急速模式 搜狗高速模式)ctrl+v粘贴图片
- javascript闭包
- Matlab中rand('state',s)和rand('state',0)
- uboot移植环境搭建笔记
- 黑马程序员_java IO流