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

一.简介

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

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

二.入门

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

[cpp]  view plain copy
  1. typedef char      s8;    //有符号8位整数  
  2. typedef short     s16;   //有符号16位整数  
  3. typedef int       s32;   //有符号32位整数  
  4. struct WAVE_TAG  
  5. {  
  6.     s8     riff[4];            //"RIFF",资源交换文件标志  
  7.     s32    fsize;              //文件大小(从下个地址开始到文件尾的总字节数)  
  8.     s8     wave[4];            //"WAVE",文件标志  
  9. };  
  10. struct WAVE_FMT  
  11. {  
  12.     s8     fmt[4];             //"fmt ",波形格式标志   
  13.     s32    chunsize;           //文件内部格式信息大小  
  14.     s16    wformattag;         //音频数据编码方式 1PCM  
  15.     s16    wchanles;           //声道数 1,2  
  16.     s32    dwsamplespersec;    //采样率 441000  
  17.     s32    dwavgbytespersec;   //波形数据传输速率(每秒平均字节数)  
  18.     s16    wblockalign;        //数据的调整数(按字节计算)  
  19.     s16    wbitspersample;     //样本数据位数  
  20. };  
  21. struct WAVE_DAT  
  22. {  
  23.     s8     data[4];            //"data",数据标志符  
  24.     s32    datasize;           //采样数据总长度   
  25. };  
  26. struct WAVE_HEAD  
  27. {  
  28.     WAVE_TAG   WaveTag;   
  29.     WAVE_FMT   WaveFmt;  
  30.     WAVE_DAT   WaveDat;  
  31. }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中实现)

[cpp]  view plain copy
  1. //定义输入/输出文件流对象,可读可写               
  2.   CFile       wavfile;                 
  3. //打开绝对路径FilePath下的wav文件,如D:\\wavfile.wav。注:必须路径是双反斜杠  
  4.   wavfile.Open( "FilePath", CFile::modeWrite|CFile::modeRead|CFile::typeBinary );  

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

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

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

[cpp]  view plain copy
  1. //将wav文件头数据取出存入wavhead结构体变量  
  2.   wavfile.Read( &wavhead, sizeof(wavhead) );  

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

[cpp]  view plain copy
  1. //将wav文件数据段(其长度存在wavhead.datasize中)全部读出存入Rbuf  
  2.   wavfile.Read( &Rbuf, wavhead.datasize );  

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

[cpp]  view plain copy
  1. //修改文件头结构体变量wavhead中的datasize成员  
  2.   wavhead.datasize = sizeof(Wbuf);  
  3. //将文件读写指针移到文件头  
  4.   wavfile.SeekToBegin();  
  5. //将修改后wav文件头wavhead存入wav文件  
  6.   wavfile.Write( &wavhead, sizeof(wavhead) );  
  7. //将新数据段(Wbuf)存入wav文件  
  8.   wavfile.Write( &Wbuf, wavhead.datasize) );  

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

[cpp]  view plain copy
  1. //结束操作,关闭wav文件    
  2.   wavfile.Close();  

三.进阶
  暂无

四.备注

  【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文件,播放结束后函数返回。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值