Wave Driver介绍

来源:互联网 发布:零度网络 下载空间 编辑:程序博客网 时间:2024/05/23 16:54
该博客旨在分享IT技术心得和实际工作中遇到问题的解决方法,以下是新浪博客地址http://blog.sina.com.cn/qianyumolu,则为分享经济、行业趋势、心灵文章等,有兴趣的朋友可以踩踩,讨论分享  我爱你小燕

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


现在工作任务太杂了,从后台到数据库,再到界面,现在还要用音频相关的。

虽然是工作也要认真记录完成。


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;





0 0
原创粉丝点击