[音频]VC下wav格式音频文件I/O操作:文件头+数据段

时间:2022-10-23 19:08:58

一.简介

    WAV是一种声音文件格式,用于保存Windows平台的音频信息资源,被Windows平台及其应用程序所广泛支持,WAV可用WINDOWS的媒体播放器打开。

    WAV文件格式是一种由微软和IBM联合开发的用于音频数字存储的标准,它采用RIFF文件格式结构,非常接近于AIFF和IFF格式。符合 RIFF(Resource Interchange File Format)规范。所有的WAV都由文件头和数据段组成,其中文件头保存了音频流的编码参数。

二.入门

  步骤1:定义波形文件头结构体WAVE_HEAD

typedef char      s8;    //有符号8位整数
typedef short s16; //有符号16位整数
typedef int s32; //有符号32位整数
struct WAVE_TAG
{
s8 riff[4]; //"RIFF",资源交换文件标志
s32 fsize; //文件大小(从下个地址开始到文件尾的总字节数)
s8 wave[4]; //"WAVE",文件标志
};
struct WAVE_FMT
{
s8 fmt[4]; //"fmt ",波形格式标志
s32 chunsize; //文件内部格式信息大小
s16 wformattag; //音频数据编码方式 1PCM
s16 wchanles; //声道数 1,2
s32 dwsamplespersec; //采样率 441000
s32 dwavgbytespersec; //波形数据传输速率(每秒平均字节数)
s16 wblockalign; //数据的调整数(按字节计算)
s16 wbitspersample; //样本数据位数
};
struct WAVE_DAT
{
s8 data[4]; //"data",数据标志符
s32 datasize; //采样数据总长度
};
struct WAVE_HEAD
{
WAVE_TAG WaveTag;
WAVE_FMT WaveFmt;
WAVE_DAT WaveDat;
}wavhead;

  声音由三个参数表示:量化位数wavhead.wbitspersample,取样频率wavhead.dwsamplespersec和声道数wavhead.wchanles量化位数有8位、16位,取样频率一般有11025Hz(11kHz) ,22050Hz(22kHz)和44100Hz(44kHz) 三种,声道有单声道和立体声之分。不过尽管音质出色,但在压缩后的文件体积过大!相对其他音频格式而言是一个缺点。其文件大小的计算方式为: 

  WAV格式文件所占容量(KB) = (取样频率 X 量化位数 X 声道) X 时间 / 8 (字节= 8bit) ,每一分钟WAV格式的音频文件的大小为10MB,其大小不随音量大小及清晰度的变化而变化。

  步骤2:使用CFile或fstream类打开wav文件(VC中实现)

    fstream类基本用法可见:http://blog.csdn.net/henjay724/article/details/8351181

    CFile类基本用法可见:http://blog.csdn.net/henjay724/article/details/8362272

  步骤3:先读取wav文件-文件头

//将wav文件头数据取出存入wavhead结构体变量
wavfile.Read( &wavhead, sizeof(wavhead) );

  步骤4:再读取wav文件-数据段

//将wav文件数据段(其长度存在wavhead.datasize中)全部读出存入Rbuf
wavfile.Read( &Rbuf, wavhead.datasize );

  步骤5:修改wav数据后重新写入wav文件

//修改文件头结构体变量wavhead中的datasize成员
wavhead.datasize = sizeof(Wbuf);
//将文件读写指针移到文件头
wavfile.SeekToBegin();
//将修改后wav文件头wavhead存入wav文件
wavfile.Write( &wavhead, sizeof(wavhead) );
//将新数据段(Wbuf)存入wav文件
wavfile.Write( &Wbuf, wavhead.datasize) );

  步骤6:操作结束,关闭文件

三.进阶
  暂无

四.备注

  【1】理论上按wavhead.datasize取出wav文件数据段大小应该比wavhead.fsize小固定长度(文件头wave成员至datasize成员所占字节大小,27Bytes),但是经测试发现使用Cool Edit 软件录制的wav文件按wavhead.datasize读取出的数据大小加上文件头大小远比wav文件本身小,说明wav中存在冗余数据。

  【2】在操作wav文件时,如向wav中加入了数据,务必修改wavhead.datasize再重新存入文件头,否则新加入的数据不能被播放器读出。但是wavhead.fsize不修改,wav也能正常播放。

  【3】如想在VC中播放wav文件可使用PlaySound()函数,首先需在代码中按序添加下列头文件(注意,顺序不能颠倒)

      #include <windows.h>
      #include <mmsystem.h>
      #pragma comment(lib, "WINMM.LIB")

  然后调用PlaySound()函数,其声明为BOOL PlaySound(LPCSTR pszSound, HMODULE hmod,DWORD fdwSound);

  示例:PlaySound( "xxFile.wav", NULL, SND_FILENAME | SND_SYNC );    //同步方式播放当前工作空间的指定xxFile.wav文件,播放结束后函数返回。