读取WAVE文件时,音频数据长度总是为零,如何解决?附代码!高分

zl198183 2007-10-15 10:26:01
if (sfilemane2==NULL)
MessageBox(NULL,"WAVE文件不存在!","警告",MB_OK);
HMMIO file1;//定义HMMIO文件句柄;

file1=mmioOpen(sfilemane2.c_str(),NULL,MMIO_READWRITE);//以读写模式打开所给的WAVE文件;
if(file1==NULL)
{
MessageBox(Null,"WAVE文件打开失败!","警告",MB_OK);
}
char style[4];//定义一个四字节的数据,用来存放文件的类型;
mmioSeek(file1,8,SEEK_SET);//定位到WAVE文件的类型位置
mmioRead(file1,style,4);
if(style[0]!='W'||style[1]!='A'||style[2]!='V'||style[3]!='E')//判断该文件是否为"WAVE"文件格式
{
MessageBox(NULL,"该文件不是WAVE格式的文件!","警告",MB_OK);
}
PCMWAVEFORMAT format; //定义PCMWAVEFORMAT结构对象,用来判断WAVE文件格式;
mmioSeek(file1,20,SEEK_SET);
//对打开的文件进行定位,此时指向WAVE文件的PCMWAVEFORMAT结构的数据;
mmioRead(file1,(char*)&format,sizeof(PCMWAVEFORMAT));//获取该结构的数据;
mmioSeek(file1,24+sizeof(PCMWAVEFORMAT),SEEK_SET);
//获取WAVE文件的声音数据的大小;
long size;
mmioRead(file1,(char*)&size,);
BYTE *pData;
pData=(BYTE*)new char[size];//根据数据的大小申请缓冲区;
mmioSeek(file1,28+sizeof(PCMWAVEFORMAT),SEEK_SET);//对文件重新定位;
mmioRead(file1,(char*)pData,size);//读取声音数据;

this->Memo1->Lines->Add(strcat(pData,""));
mmioClose(file1, MMIO_FHOPEN);//关闭WAVE文件
WAVE头文件定义如下:
typedef struct _TWavHeader
{
long rId;
long rLen;
long wId;
long fId;
long fLen;
WORD wFormatTag;
WORD nChannels;
long nSamplesPerSec;
long nAvgBytesPerSec;
WORD nBlockAlign;
WORD wBitsPerSample;
long dId;
long wSampleLength;
}TWavHeader;
...全文
632 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
archimic 2008-10-08
  • 打赏
  • 举报
回复
typedef struct waveformat_tag
{
WORD wFormatTag; /* format type */
WORD nChannels; /* number of channels (i.e. mono, stereo, etc.) */
DWORD nSamplesPerSec; /* sample rate */
DWORD nAvgBytesPerSec; /* for buffer estimation */
WORD nBlockAlign; /* block size of data */
} WAVEFORMAT;

typedef struct pcmwaveformat_tag
{
WAVEFORMAT wf;
WORD wBitsPerSample;
} PCMWAVEFORMAT;

struct TWavHeader
{
char rId[4]; //标志符(RIFF)
DWORD rLen; //数据大小,包括数据头的大小和音频文件的大小
char wId[4]; //格式类型("WAVE")
char fId[4]; //"fmt"
DWORD fLen; //Sizeof(PCMWAVEFORMAT)
PCMWAVEFORMAT wavFormat;
char dId[4]; //"data"
DWORD wSampleLength; //音频数据的大小
};
fjye 2007-10-15
  • 打赏
  • 举报
回复
wav文件包括头和数据两部分,其结构如下:(从文件头开始依次排列)
1)首先是字符串“RIFF” ,占4个字节。
2)波形块的大小:DWORD,占4字节。波形块的大小=(文件大小-8)
3)字符串"WAVE",占4个字节。
4)字符串“fmt ”,占4个字节,注意fmt后有个空格字符(0x20)。
5)格式块的大小,DWORD,占4个字节
6)格式块,VC中用WAVEFORMATEX结构体描述,占18个字节,可用sizeof(WAVEFORMATEX)计算。
其中WAVEFORMATEX结构体的定义为:(更详细的描述可以参考msdn)
typedef struct tWAVEFORMATEX
{
WORD wFormatTag; /* format type */
WORD nChannels; /* number of channels (i.e. mono, stereo...) */
DWORD nSamplesPerSec; /* sample rate */
DWORD nAvgBytesPerSec; /* for buffer estimation */
WORD nBlockAlign; /* block size of data */
WORD wBitsPerSample; /* number of bits per sample of mono data */
WORD cbSize; /* the count in bytes of the size of */
/* extra information (after cbSize) */
} WAVEFORMATEX, *PWAVEFORMATEX, NEAR *NPWAVEFORMATEX, FAR *LPWAVEFORMATEX;

7)字符串"data",占4个字节。
8)波形数据的大小,DWORD,占4个字节。
9)声音数据,大小在8)中描述。

以下是一个波形文件样本的头部:
00000000h: 52 49 46 46 E6 E4 05 00 57 41 56 45 66 6D 74 20 ; RIFF驿..WAVEfmt
00000010h: 12 00 00 00 01 00 01 00 40 1F 00 00 80 3E 00 00 ; ........@...€>..
00000020h: 02 00 10 00 00 00 64 61 74 61 C0 E4 05 00 ; ......data冷..
从该样本可以看出:
该波形文件波形块的大小为386278(0x0005E4E6),波形文件大小为:386278+8 =386286字节;
格式块的大小(WAVEFORMATEX结构体)为18字节;
波形数据的大小为386240字节(0x0005E4C0);

就是说你想要的数据应该就在这两个数据其中一个

格式块(WAVEFORMATEX结构体)中定义的声音数据属性为:
wFormatTag=0x0001 即WAVE_FORMAT_PCM ;
nChannels = 0x0001 即单声道;
nSamplesPerSec = 0x00001F40 即采样率8000Hz;
nAvgBytesPerSec = 0x00003E80 即平均字节速率16000字节(16bit量化),可以根据该数据估计缓冲区的大小;
nBlockAlign = 0x0002 即块联合为2字节(16bit量化,2字节表示一个采样点,播放时必须从以块为单位从块头开始播放);
wBitsPerSample = 0x0010 即每个采样点的比特值为16(16bit量化)。nBlockAlign值即由该值除以8计算出来;
cbSize不使用,填0x0000。
Waiting4you 2007-10-15
  • 打赏
  • 举报
回复
你应该使用mmioDescend/mmioAscend功能来读写wave文件,网上很多依据wave格式直接读的方法其实是针对linux的,windows下对riff文件是直接支持的

    if (sfilemane2==NULL)
MessageBox(NULL,"WAVE文件不存在!","警告",MB_OK);
HMMIO file1;//定义HMMIO文件句柄;

file1=mmioOpen(sfilemane2.c_str(),NULL,MMIO_READWRITE);//以读写模式打开所给的WAVE文件;
if(file1==NULL)
{
MessageBox(Null,"WAVE文件打开失败!","警告",MB_OK);
}

MMCKINFO mmckinfo;
mmckinfo.fccType = mmioFOURCC('W', 'A', 'V', 'E');
if(mmioDescend(file1, (LPMMCKINFO) &mmckinfo,NULL,MMIO_FINDRIFF)==MMSYSERR_NOERROR)
{
MMCKINFO mmckfmt;
mmckfmt.ckid = mmioFOURCC('f', 'm', 't', ' ');
if(mmioDescend(file1, (LPMMCKINFO) &mmckfmt,&mmckinfo,MMIO_FINDCHUNK)==MMSYSERR_NOERROR)
{
WAVEFORMATEX *format=(WAVEFORMATEX*)malloc(mmckfmt.cksize);
mmioRead(file1, (HPSTR)format,mmckfmt.cksize);
mmioAscend(file1, &mmckfmt, 0);
}

MMCKINFO mmckdata;
mmckdata.ckid = mmioFOURCC('d', 'a', 't', 'a');
if(mmioDescend(file1, (LPMMCKINFO) &mmckdata,&mmckinfo,MMIO_FINDCHUNK)==MMSYSERR_NOERROR)
{
BYTE *pData=new BYTE[mmckdata.cksize];
mmioRead(file1, (HPSTR)pData,mmckdata.cksize);
mmioAscend(file1, &mmckfmt, 0);
ShowMessage(mmckdata.cksize);
}
}
mmioClose(file1, MMIO_FHOPEN);//关闭WAVE文件
zl198183 2007-10-15
  • 打赏
  • 举报
回复
创建WAVE文件头时,波形数据的大小写的是0,录音完成后也没有处理,怎么才能在头文件内得到波形数据的大小呢?如果要想在头文件中加入波形数据的大小,怎么计算?

1,221

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧