user-0 提问: C语音读取WAV文件，头文件中DataID为空，求大神帮忙看看

回复:
user: user-1
content: 引用 10 楼 yulitingfeng 的回复:#include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h>  #pragma pack(1)    struct WavHead_ { 	char ChunkID[4]; //ChunkID is "RIFF' 	unsigned int Chunksize; //RIFF WAVE Chunk 大小 	char ChunkType[4]; //Yype is 'WAVE' 	//char Format[4]; 	char FormatID[4]; //FORmatID IS 'fmt' 	int dwFmtlen; 	int Formattag;//编码方式，一般为0x0001 	int ChannelNum; //声道数目，1--单声道；2--双声道 	int SamplePersec; //采样频率 	int AveBytePersec; //每秒平均字节数 	short BitsperSample;//每个采样点的bit 	char FactID[4]; //FactID is 'fact' 	int Factsize; 	int FactData; 	char DataID[4];//DataId is 'data' 	long DataSize; 	long WavData; 	long  SubChun2Size;     //long SampleNum; }WavHead;  //void wave_generator(FILE *fpwav, wav_pcm_header44 *phwav);   int main() {     FILE *fpwav = NULL;     struct WavHead_ hWAV;      fpwav = fopen("test.wav","rb");     if(fpwav == NULL) {         printf("fail to open file");         return -1;     }     printf("open ok\n");     fread(&hWAV, sizeof(WavHead), 1, fpwav);     printf("fread head ok\n");      printf("%s,%s,%s,\n",hWAV.DataID,hWAV.FactID,hWAV.ChunkType);      if ((0 == memcmp(hWAV.ChunkID,"RIFF",4))&&(0 == memcmp(hWAV.FormatID,"fmt",4),4)&&(0 == memcmp(hWAV.DataID,"data",4))) {         printf("wave audio data format:\n");         printf("Channel num:%d\n",hWAV.ChannelNum);         printf("SampleRate:%dHz\n",hWAV.SamplePersec);         printf("BitesperSample:%d bits\n",hWAV.AveBytePersec);         //printf("audio data size : %d",)     }      fclose(fpwav);     fpwav = NULL;     return 0;  }修改后的，可能会有问题，需认真对比wav的数据结构。  输出：open ok fread head ok data串,fact,WAVEfmt , wave audio data format: Channel num:22050 SampleRate:44100Hz BitesperSample:1048578 bits  这个#pragma pack(1) 事至关重要的！ 谢谢！

user: user-2
content: #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h>  #pragma pack(push,1) struct WavHead {     char   ChunkID[4];    //ChunkID is "RIFF'     short  Chunksize;     //RIFF WAVE Chunk 大小     char   ChunkType[4];  //Yype is 'WAVE'     //char Format[4];     char   FormatID[4];   //FORmatID IS 'fmt'     short    dwFmtlen;     short    Formattag;     //编码方式，一般为0x0001     short  ChannelNum;    //声道数目，1--单声道；2--双声道     long   SamplePersec;  //采样频率     long   AveBytePersec; //每秒平均字节数     short  BitsperSample; //每个采样点的bit     char   FactID[4];     //FactID is 'fact'     long   Factsize;     long   FactData;     char   DataID[4];     //DataId is 'data'     long   DataSize;     long   WavData;     long   SubChun2Size;     //long SampleNum; }; #pragma pack(pop)  //void wave_generator(FILE *fpwav, wav_pcm_header44 *phwav);   int main() {     FILE *fpwav = NULL;     struct WavHead hWAV;      fpwav = fopen("test.wav","rb");     if(fpwav == NULL) {         printf("fail to open file");         return -1;     }     printf("open ok\n");     fread(&hWAV, sizeof(WavHead), 1, fpwav);     printf("fread head ok\n");      printf("%s\n",hWAV.DataID);       if ((0 == memcmp(hWAV.ChunkID,"RIFF",4))&&(0 == memcmp(hWAV.FormatID,"fmt",4),4)&&(0 == memcmp(hWAV.DataID,"data",4))) {         printf("wave audio data format:\n");         printf("Channel num:%d\n",hWAV.ChannelNum);         printf("SampleRate:%dHz\n",hWAV.SamplePersec);         printf("BitesperSample:%d bits\n",hWAV.AveBytePersec);         //printf("audio data size : %d",)     }      fclose(fpwav);     fpwav = NULL;     return 0;  }

user: user-3
content: 定义结构体之前配置：  #pragma pack(1)  就是紧凑模式，这样字段就会一个一个的挨着放。  否则的话，编译器会在一些字段后面插入空的字节，用来对齐，以实现较高的处理效率。  引用 2 楼 xinsuixiaofeiyu 的回复:怎样才是紧凑模式呢？如果设定对齐方式，该设定多少字节对齐呢？求大神详细解释下了。[quote=引用 1 楼 turingo 的回复:] 结构体要用紧凑模式，不然又会字节对齐的问题：  #pragma pack(1)   [quote=引用 楼主 xinsuixiaofeiyu 的回复:] c语言写的一个读取wav音频文件的小程序，调试发现DataID内容为空，但应该为'data'，不知道原因，音频文件为一首wav的歌曲，代码如下： #include<stdio.h> #include<stdlib.h> #include <STRING.H> #include<math.h> typedef short DWORD; struct WavHead { 	char ChunkID[4]; //ChunkID is "RIFF' 	DWORD Chunksize; //RIFF WAVE Chunk 大小 	char ChunkType[4]; //Yype is 'WAVE' 	//char Format[4]; 	char FormatID[4]; //FORmatID IS 'fmt' 	int dwFmtlen; 	int Formattag;//编码方式，一般为0x0001 	short ChannelNum; //声道数目，1--单声道；2--双声道 	long SamplePersec; //采样频率 	long AveBytePersec; //每秒平均字节数 	short BitsperSample;//每个采样点的bit 	char FactID[4]; //FactID is 'fact' 	long Factsize; 	long FactData; 	char DataID[4];//DataId is 'data' 	long DataSize; 	long WavData; 	long SubChun2Size; 	//long SampleNum; };  //void wave_generator(FILE *fpwav, wav_pcm_header44 *phwav);   int main() { 	FILE *fpwav = NULL; 	struct WavHead hWAV; 	 	fpwav = fopen("test.wav","rb"); 	if(fpwav == NULL) 	{ 		printf("fail to open file"); 		return -1; 	} 	printf("open ok\n"); 	fread(&hWAV, sizeof(WavHead), 1, fpwav); 	printf("fread head ok\n");  	printf("%s\n",hWAV.DataID);  	 	if ((0 == memcmp(hWAV.ChunkID,"RIFF",4))&&(0 == memcmp(hWAV.FormatID,"fmt",4),4)&&(0 == memcmp(hWAV.DataID,"data",4))) 	{ 		printf("wave audio data format:\n"); 		printf("Channel num:%d\n",hWAV.ChannelNum); 		printf("SampleRate:%dHz\n",hWAV.SamplePersec); 		printf("BitesperSample:%d bits\n",hWAV.AveBytePersec); 		//printf("audio data size : %d",) 	} 	 	fclose(fpwav); 	fpwav = NULL; return 0; 	 }[/quote][/quote]

user: user-0
content: 怎样才是紧凑模式呢？如果设定对齐方式，该设定多少字节对齐呢？求大神详细解释下了。引用 1 楼 turingo 的回复:结构体要用紧凑模式，不然又会字节对齐的问题：  #pragma pack(1)   [quote=引用 楼主 xinsuixiaofeiyu 的回复:] c语言写的一个读取wav音频文件的小程序，调试发现DataID内容为空，但应该为'data'，不知道原因，音频文件为一首wav的歌曲，代码如下： #include<stdio.h> #include<stdlib.h> #include <STRING.H> #include<math.h> typedef short DWORD; struct WavHead { 	char ChunkID[4]; //ChunkID is "RIFF' 	DWORD Chunksize; //RIFF WAVE Chunk 大小 	char ChunkType[4]; //Yype is 'WAVE' 	//char Format[4]; 	char FormatID[4]; //FORmatID IS 'fmt' 	int dwFmtlen; 	int Formattag;//编码方式，一般为0x0001 	short ChannelNum; //声道数目，1--单声道；2--双声道 	long SamplePersec; //采样频率 	long AveBytePersec; //每秒平均字节数 	short BitsperSample;//每个采样点的bit 	char FactID[4]; //FactID is 'fact' 	long Factsize; 	long FactData; 	char DataID[4];//DataId is 'data' 	long DataSize; 	long WavData; 	long SubChun2Size; 	//long SampleNum; };  //void wave_generator(FILE *fpwav, wav_pcm_header44 *phwav);   int main() { 	FILE *fpwav = NULL; 	struct WavHead hWAV; 	 	fpwav = fopen("test.wav","rb"); 	if(fpwav == NULL) 	{ 		printf("fail to open file"); 		return -1; 	} 	printf("open ok\n"); 	fread(&hWAV, sizeof(WavHead), 1, fpwav); 	printf("fread head ok\n");  	printf("%s\n",hWAV.DataID);  	 	if ((0 == memcmp(hWAV.ChunkID,"RIFF",4))&&(0 == memcmp(hWAV.FormatID,"fmt",4),4)&&(0 == memcmp(hWAV.DataID,"data",4))) 	{ 		printf("wave audio data format:\n"); 		printf("Channel num:%d\n",hWAV.ChannelNum); 		printf("SampleRate:%dHz\n",hWAV.SamplePersec); 		printf("BitesperSample:%d bits\n",hWAV.AveBytePersec); 		//printf("audio data size : %d",) 	} 	 	fclose(fpwav); 	fpwav = NULL; return 0; 	 }[/quote]

user: user-4
content: #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h>  #pragma pack(1)    struct WavHead_ { 	char ChunkID[4]; //ChunkID is "RIFF' 	unsigned int Chunksize; //RIFF WAVE Chunk 大小 	char ChunkType[4]; //Yype is 'WAVE' 	//char Format[4]; 	char FormatID[4]; //FORmatID IS 'fmt' 	int dwFmtlen; 	int Formattag;//编码方式，一般为0x0001 	int ChannelNum; //声道数目，1--单声道；2--双声道 	int SamplePersec; //采样频率 	int AveBytePersec; //每秒平均字节数 	short BitsperSample;//每个采样点的bit 	char FactID[4]; //FactID is 'fact' 	int Factsize; 	int FactData; 	char DataID[4];//DataId is 'data' 	long DataSize; 	long WavData; 	long  SubChun2Size;     //long SampleNum; }WavHead;  //void wave_generator(FILE *fpwav, wav_pcm_header44 *phwav);   int main() {     FILE *fpwav = NULL;     struct WavHead_ hWAV;      fpwav = fopen("test.wav","rb");     if(fpwav == NULL) {         printf("fail to open file");         return -1;     }     printf("open ok\n");     fread(&hWAV, sizeof(WavHead), 1, fpwav);     printf("fread head ok\n");      printf("%s,%s,%s,\n",hWAV.DataID,hWAV.FactID,hWAV.ChunkType);      if ((0 == memcmp(hWAV.ChunkID,"RIFF",4))&&(0 == memcmp(hWAV.FormatID,"fmt",4),4)&&(0 == memcmp(hWAV.DataID,"data",4))) {         printf("wave audio data format:\n");         printf("Channel num:%d\n",hWAV.ChannelNum);         printf("SampleRate:%dHz\n",hWAV.SamplePersec);         printf("BitesperSample:%d bits\n",hWAV.AveBytePersec);         //printf("audio data size : %d",)     }      fclose(fpwav);     fpwav = NULL;     return 0;  }修改后的，可能会有问题，需认真对比wav的数据结构。  输出：open ok fread head ok data串,fact,WAVEfmt , wave audio data format: Channel num:22050 SampleRate:44100Hz BitesperSample:1048578 bits

user: user-4
content: 你可以用ultraedit 来查看wav文件的数据流。

user: user-2
content: C:\windows_2000_source_code\win2k\private\windows\shell\control\mmsys\sound.c /*    -    -    -    -    -    -    -    -    */ // //    sound.c // //    Copyright (C) 1994 Microsoft Corporation.  All Rights Reserved. // /*    -    -    -    -    -    -    -    -    */  #define STRICT #include <windows.h> #include <windowsx.h> #include <mmsystem.h> #include <mmddk.h> #include "sound.h" #include <tchar.h>  /*    -    -    -    -    -    -    -    -    */ typedef struct tagSOUND FAR *PSOUND; typedef struct tagSOUND {     WAVEHDR        header;     LPBYTE        pbData;     DWORD        cbLength;     LPWAVEFORMATEX    lpwfx;     HGLOBAL        hgData;     HWAVEOUT    hwave;     HWND        hwndNotify; } SOUND;  typedef struct {     FOURCC    fccRiff;     DWORD    cbSize;     FOURCC    fccWave; } FILEHEADER,  *LPFILEHEADER;   typedef struct {     DWORD    dwCKID;     DWORD    dwSize; } CHUNKHEADER,  *LPCHUNKHEADER;  #define    RIFF_FILE    MAKEFOURCC('R','I','F','F') #define    RIFF_WAVE    MAKEFOURCC('W','A','V','E') #define    RIFF_FORMAT    MAKEFOURCC('f','m','t',' ') #define    RIFF_DATA    MAKEFOURCC('d','a','t','a')  /*    -    -    -    -    -    -    -    -    */ #ifdef DEBUG #define    STATIC #else #define    STATIC    static #endif  typedef CHUNKHEADER UNALIGNED FAR *ULPCHUNKHEADER; typedef WAVEFORMATEX UNALIGNED FAR *ULPWAVEFORMATEX;  /*    -    -    -    -    -    -    -    -    */ STATIC MMRESULT NEAR PASCAL soundInitWaveHeader(     PSOUND    ps) {     size_t cbWFX;     ULPWAVEFORMATEX    pwfx;     ULPCHUNKHEADER    pckhdr;     LPFILEHEADER    pfhdr;     LPBYTE        pbData;     DWORD        dwFileSize;     DWORD        dwCurPos;      if (ps->cbLength < sizeof(FILEHEADER))         return MMSYSERR_INVALPARAM;     pfhdr = (LPFILEHEADER)ps->pbData;     if ((pfhdr->fccRiff != RIFF_FILE) || (pfhdr->fccWave != RIFF_WAVE))         return MMSYSERR_NOTSUPPORTED;     dwFileSize = pfhdr->cbSize;     dwCurPos = sizeof(FILEHEADER);     pbData = (LPBYTE)ps->pbData + sizeof(FILEHEADER);     if (ps->cbLength < dwFileSize)         return MMSYSERR_INVALPARAM;     for (;;)     {         pckhdr = (ULPCHUNKHEADER)pbData;         if (pckhdr->dwCKID == RIFF_FORMAT)             break;         dwCurPos += pckhdr->dwSize + sizeof(CHUNKHEADER);         if (dwCurPos >= dwFileSize)             return MMSYSERR_INVALPARAM;         pbData += pckhdr->dwSize + sizeof(CHUNKHEADER);     }     pwfx = (ULPWAVEFORMATEX)(pbData + sizeof(CHUNKHEADER));      cbWFX = sizeof(WAVEFORMATEX);     if (pwfx->wFormatTag!=WAVE_FORMAT_PCM)     {         cbWFX += pwfx->cbSize;     }      if ((ps->lpwfx = (LPWAVEFORMATEX)GlobalAlloc (GMEM_FIXED, cbWFX)) == 0)         return MMSYSERR_NOMEM;      memcpy ((char *)ps->lpwfx, pwfx, cbWFX);      pbData = pbData + ((ULPCHUNKHEADER)pbData)->dwSize + sizeof(CHUNKHEADER);     for (;;)     {         pckhdr = (ULPCHUNKHEADER)pbData;         if (pckhdr->dwCKID == RIFF_DATA)             break;         dwCurPos += pckhdr->dwSize + sizeof(CHUNKHEADER);         if (dwCurPos >= dwFileSize)         {             GlobalFree ((HGLOBAL)ps->lpwfx);             ps->lpwfx = NULL;             return MMSYSERR_INVALPARAM;         }         pbData += pckhdr->dwSize + sizeof(CHUNKHEADER);     }     ps->header.lpData = pbData + sizeof(CHUNKHEADER);     ps->header.dwBufferLength = pckhdr->dwSize;     ps->header.dwBytesRecorded = 0;     ps->header.dwUser = (DWORD_PTR)ps;     ps->header.dwFlags = 0;     ps->header.dwLoops = 0;     ps->header.lpNext = NULL;     ps->header.reserved = 0;     return MMSYSERR_NOERROR; }  /*    -    -    -    -    -    -    -    -    */ STATIC MMRESULT NEAR PASCAL soundLoadFile(     LPCTSTR    pszSound,     HWND    hwndNotify,     PSOUND    ps) {     HFILE        hf;     MMRESULT    mmr;      if ((hf = HandleToUlong(CreateFile(pszSound,GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL))) != HFILE_ERROR)     {         ps->cbLength = _llseek(hf, 0L, SEEK_END);         _llseek(hf, 0L, SEEK_SET);         if (ps->hgData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, ps->cbLength))         {             if (ps->pbData = GlobalLock(ps->hgData))             {                 if (_hread(hf, ps->pbData, ps->cbLength) == (LONG)ps->cbLength)                 {                     if (!(mmr = soundInitWaveHeader(ps)))                     {                         _lclose(hf);                         ps->hwndNotify = hwndNotify;                         return MMSYSERR_NOERROR;                     }                 }                 else                     mmr = MMSYSERR_ERROR;                 GlobalUnlock(ps->hgData);             }             else                 mmr = MMSYSERR_ERROR;             GlobalFree(ps->hgData);         }         else             mmr = MMSYSERR_NOMEM;         _lclose(hf);     }     else         mmr = MMSYSERR_ERROR;      return mmr; }  /*    -    -    -    -    -    -    -    -    */ void FAR PASCAL soundOnDone(     HSOUND    hs) {     PSOUND        ps;      ps = (PSOUND)hs;     waveOutUnprepareHeader(ps->hwave, &ps->header, sizeof(WAVEHDR));     waveOutClose(ps->hwave);     ps->hwave = NULL; }  /*    -    -    -    -    -    -    -    -    */ MMRESULT FAR PASCAL soundOpen(     LPCTSTR    pszSound,     HWND    hwndNotify,     PHSOUND    phs) {     MMRESULT    mmr;      if (!(*phs = (HSOUND)LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, sizeof(SOUND))))         return MMSYSERR_NOMEM;     if (mmr = soundLoadFile(pszSound, hwndNotify, (PSOUND)*phs))         LocalFree((HLOCAL)*phs);     return mmr; }  /*    -    -    -    -    -    -    -    -    */ MMRESULT FAR PASCAL soundClose(     HSOUND    hs) {     PSOUND        ps;     MMRESULT    mmr;      if (mmr = soundStop(hs))         return mmr;     ps = (PSOUND)hs;     if (ps->lpwfx != NULL) {         GlobalFree ((HGLOBAL)ps->lpwfx);         ps->lpwfx = NULL;     }     GlobalUnlock(ps->hgData);     GlobalFree(ps->hgData);     LocalFree((HLOCAL)hs);     return MMSYSERR_NOERROR; }  /*    -    -    -    -    -    -    -    -    */ MMRESULT FAR PASCAL soundPlay(     HSOUND    hs) {     PSOUND        ps;     MMRESULT    mmr;      if (mmr = soundStop(hs))         return mmr;     ps = (PSOUND)hs;     if (!(mmr = waveOutOpen(&ps->hwave, WAVE_MAPPER, ps->lpwfx, (DWORD_PTR)ps->hwndNotify, (DWORD_PTR)ps, CALLBACK_WINDOW | WAVE_ALLOWSYNC)))     {         ps->header.dwFlags &= ~WHDR_DONE;         if (!(mmr = waveOutPrepareHeader(ps->hwave, &ps->header, sizeof(WAVEHDR))))         {             if (!(mmr = waveOutWrite(ps->hwave, &ps->header, sizeof(WAVEHDR))))                 return MMSYSERR_NOERROR;             waveOutUnprepareHeader(ps->hwave, &ps->header, sizeof(WAVEHDR));         }         waveOutClose(ps->hwave);         ps->hwave = NULL;     }     return mmr; }  /*    -    -    -    -    -    -    -    -    */ MMRESULT FAR PASCAL soundStop(     HSOUND    hs) {     PSOUND        ps;     MSG        msg;      ps = (PSOUND)hs;     if (ps->hwave)         waveOutReset(ps->hwave);     if (IsWindow(ps->hwndNotify))     while (PeekMessage(&msg, ps->hwndNotify, MM_WOM_OPEN, MM_WOM_DONE, PM_REMOVE))     {         DispatchMessage(&msg);     }     return MMSYSERR_NOERROR; }  /*    -    -    -    -    -    -    -    -    */

user: user-2
content: 参考C:\windows_2000_source_code\win2k\private\windows\shell\control\mmsys\sound.c ... STATIC MMRESULT NEAR PASCAL soundInitWaveHeader(     PSOUND    ps) {     size_t cbWFX;     ULPWAVEFORMATEX    pwfx;     ULPCHUNKHEADER    pckhdr;     LPFILEHEADER    pfhdr;     LPBYTE        pbData;     DWORD        dwFileSize;     DWORD        dwCurPos;      if (ps->cbLength < sizeof(FILEHEADER))         return MMSYSERR_INVALPARAM;     pfhdr = (LPFILEHEADER)ps->pbData;     if ((pfhdr->fccRiff != RIFF_FILE) || (pfhdr->fccWave != RIFF_WAVE))         return MMSYSERR_NOTSUPPORTED;     dwFileSize = pfhdr->cbSize;     dwCurPos = sizeof(FILEHEADER);     pbData = (LPBYTE)ps->pbData + sizeof(FILEHEADER);     if (ps->cbLength < dwFileSize)         return MMSYSERR_INVALPARAM;     for (;;)     {         pckhdr = (ULPCHUNKHEADER)pbData;         if (pckhdr->dwCKID == RIFF_FORMAT)             break;         dwCurPos += pckhdr->dwSize + sizeof(CHUNKHEADER);         if (dwCurPos >= dwFileSize)             return MMSYSERR_INVALPARAM;         pbData += pckhdr->dwSize + sizeof(CHUNKHEADER);     }     pwfx = (ULPWAVEFORMATEX)(pbData + sizeof(CHUNKHEADER));      cbWFX = sizeof(WAVEFORMATEX);     if (pwfx->wFormatTag!=WAVE_FORMAT_PCM)     {         cbWFX += pwfx->cbSize;     }      if ((ps->lpwfx = (LPWAVEFORMATEX)GlobalAlloc (GMEM_FIXED, cbWFX)) == 0)         return MMSYSERR_NOMEM;      memcpy ((char *)ps->lpwfx, pwfx, cbWFX);      pbData = pbData + ((ULPCHUNKHEADER)pbData)->dwSize + sizeof(CHUNKHEADER);     for (;;)     {         pckhdr = (ULPCHUNKHEADER)pbData;         if (pckhdr->dwCKID == RIFF_DATA)             break;         dwCurPos += pckhdr->dwSize + sizeof(CHUNKHEADER);         if (dwCurPos >= dwFileSize)         {             GlobalFree ((HGLOBAL)ps->lpwfx);             ps->lpwfx = NULL;             return MMSYSERR_INVALPARAM;         }         pbData += pckhdr->dwSize + sizeof(CHUNKHEADER);     }     ps->header.lpData = pbData + sizeof(CHUNKHEADER);     ps->header.dwBufferLength = pckhdr->dwSize;     ps->header.dwBytesRecorded = 0;     ps->header.dwUser = (DWORD_PTR)ps;     ps->header.dwFlags = 0;     ps->header.dwLoops = 0;     ps->header.lpNext = NULL;     ps->header.reserved = 0;     return MMSYSERR_NOERROR; } ... STATIC MMRESULT NEAR PASCAL soundLoadFile(     LPCTSTR    pszSound,     HWND    hwndNotify,     PSOUND    ps) {     HFILE        hf;     MMRESULT    mmr;      if ((hf = HandleToUlong(CreateFile(pszSound,GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL))) != HFILE_ERROR)     {         ps->cbLength = _llseek(hf, 0L, SEEK_END);         _llseek(hf, 0L, SEEK_SET);         if (ps->hgData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, ps->cbLength))         {             if (ps->pbData = GlobalLock(ps->hgData))             {                 if (_hread(hf, ps->pbData, ps->cbLength) == (LONG)ps->cbLength)                 {                     if (!(mmr = soundInitWaveHeader(ps)))                     {                         _lclose(hf);                         ps->hwndNotify = hwndNotify;                         return MMSYSERR_NOERROR;                     }                 }                 else                     mmr = MMSYSERR_ERROR;                 GlobalUnlock(ps->hgData);             }             else                 mmr = MMSYSERR_ERROR;             GlobalFree(ps->hgData);         }         else             mmr = MMSYSERR_NOMEM;         _lclose(hf);     }     else         mmr = MMSYSERR_ERROR;      return mmr; } ...

user: user-0
content: 正解，文件头格式需和文件对应，一般应该是44字节。引用 5 楼 user-5 的回复:wav由若干个块组成，不一定马上就是fmt，也不一定有fact，分析应该时循序读入4byte块名+4byte块的大小，然后推敲出下一个块的位置，多声道的话fmt块也不是你列出的那种格式，所以先找格式规范看看先...

user: user-5
content: wav由若干个块组成，不一定马上就是fmt，也不一定有fact，分析应该时循序读入4byte块名+4byte块的大小，然后推敲出下一个块的位置，多声道的话fmt块也不是你列出的那种格式，所以先找格式规范看看先...

user: user-3
content: 结构体要用紧凑模式，不然又会字节对齐的问题：  #pragma pack(1)  引用 楼主 xinsuixiaofeiyu 的回复:c语言写的一个读取wav音频文件的小程序，调试发现DataID内容为空，但应该为'data'，不知道原因，音频文件为一首wav的歌曲，代码如下： #include<stdio.h> #include<stdlib.h> #include <STRING.H> #include<math.h> typedef short DWORD; struct WavHead { 	char ChunkID[4]; //ChunkID is "RIFF' 	DWORD Chunksize; //RIFF WAVE Chunk 大小 	char ChunkType[4]; //Yype is 'WAVE' 	//char Format[4]; 	char FormatID[4]; //FORmatID IS 'fmt' 	int dwFmtlen; 	int Formattag;//编码方式，一般为0x0001 	short ChannelNum; //声道数目，1--单声道；2--双声道 	long SamplePersec; //采样频率 	long AveBytePersec; //每秒平均字节数 	short BitsperSample;//每个采样点的bit 	char FactID[4]; //FactID is 'fact' 	long Factsize; 	long FactData; 	char DataID[4];//DataId is 'data' 	long DataSize; 	long WavData; 	long SubChun2Size; 	//long SampleNum; };  //void wave_generator(FILE *fpwav, wav_pcm_header44 *phwav);   int main() { 	FILE *fpwav = NULL; 	struct WavHead hWAV; 	 	fpwav = fopen("test.wav","rb"); 	if(fpwav == NULL) 	{ 		printf("fail to open file"); 		return -1; 	} 	printf("open ok\n"); 	fread(&hWAV, sizeof(WavHead), 1, fpwav); 	printf("fread head ok\n");  	printf("%s\n",hWAV.DataID);  	 	if ((0 == memcmp(hWAV.ChunkID,"RIFF",4))&&(0 == memcmp(hWAV.FormatID,"fmt",4),4)&&(0 == memcmp(hWAV.DataID,"data",4))) 	{ 		printf("wave audio data format:\n"); 		printf("Channel num:%d\n",hWAV.ChannelNum); 		printf("SampleRate:%dHz\n",hWAV.SamplePersec); 		printf("BitesperSample:%d bits\n",hWAV.AveBytePersec); 		//printf("audio data size : %d",) 	} 	 	fclose(fpwav); 	fpwav = NULL; return 0; 	 }