读取Wav头文件产生奇怪结果的代码? C

时间:2013-02-19 01:42:42

标签: c wav

我需要从wave文件中读取标头变量并显示它们是什么。我使用以下代码,但我的输出数字太大了。我已经搜索了几个小时的解决方案。非常感谢帮助!谢谢。我从https://ccrma.stanford.edu/courses/422/projects/WaveFormat/

获得了wave声音文件格式

输出: Wav file header information: Filesize 3884 bytes RIFF header RIFF WAVE header WAVE Subchunk1ID fmt Chunk Size (based on bits used) 604962816 Subchunk1Size 268435456 Sampling Rate 288030720 Bits Per Sample 2048 AudioFormat 256 Number of channels 2048 Byte Rate 288030720 Subchunk2ID Subchunk2Size 1684108385

以下是来源:

#include <stdio.h>
#include <stdlib.h>

typedef struct  WAV_HEADER
{
char                RIFF[4];        
int                 ChunkSize;     
char                WAVE[4];       
char                fmt[4];        
int                 Subchunk1Size;                              
short int           AudioFormat;  
short int           NumOfChan;      
int                 SamplesPerSec;  
int                 bytesPerSec;    
short int           blockAlign;    
short int           bitsPerSample;  
int                 Subchunk2Size; 
char                Subchunk2ID[4];
}wav_hdr; 

int getFileSize(FILE *inFile); 
int main(int argc,char *argv[])
{
//check startup conditions
if(argc >= 2); //we have enough arguments -- continue
else { printf("\nUSAGE: program requires a filename as an argument -- please try again\n"); exit(0);}

wav_hdr wavHeader;
FILE *wavFile;
int headerSize = sizeof(wav_hdr),filelength = 0;
wavFile = fopen(argv[1],"r");
if(wavFile == NULL)
{
    printf("Unable to open wave file\n");
    exit(EXIT_FAILURE);
}
fread(&wavHeader,headerSize,1,wavFile);
filelength = getFileSize(wavFile);
fclose(wavFile);
printf("\nWav file header information:\n");
printf("Filesize\t\t\t%d bytes\n",filelength);
printf("RIFF header\t\t\t%c%c%c%c\n",wavHeader.RIFF[0],wavHeader.RIFF[1],wavHeader.RIFF[2],wavHeader.RIFF[3]);
printf("WAVE     header\t\t\t%c%c%c%c\n",wavHeader.WAVE[0],wavHeader.WAVE[1],wavHeader.WAVE[2],wavHeader.WAVE[3]);
     printf("Subchunk1ID\t\t\t%c%c%c%c\n",wavHeader.fmt[0],wavHeader.fmt[1],wavHeader.fmt[2],wavHeader.fmt[3]);
printf("Chunk Size (based on bits used)\t%d\n",wavHeader.ChunkSize);
printf("Subchunk1Size\t\t\t%d\n",wavHeader.Subchunk1Size);
printf("Sampling Rate\t\t\t%d\n",wavHeader.SamplesPerSec); //Sampling frequency of the wav file
printf("Bits Per Sample\t\t\t%d\n",wavHeader.bitsPerSample); //Number of bits used per sample
printf("AudioFormat\t\t\t%d\n",wavHeader.AudioFormat);
printf("Number of channels\t\t%d\n",wavHeader.bitsPerSample);     //Number of channels (mono=1/sterio=2)
printf("Byte Rate\t\t\t%d\n",wavHeader.bytesPerSec);   //Number of bytes per second
printf("Subchunk2ID\t\t\t%c%c%c%c\n",wavHeader.Subchunk2ID[0],wavHeader.Subchunk2ID[1],wavHeader.Subchunk2ID[2],wavHeader.Subchunk2ID[3]);
printf("Subchunk2Size\t\t\t%d\n",wavHeader.Subchunk2Size);
printf("\n");
return 0;
}

int getFileSize(FILE *inFile)
{
int fileSize = 0;
fseek(inFile,0,SEEK_END);
fileSize=ftell(inFile);
fseek(inFile,0,SEEK_SET);
return fileSize;
}`

2 个答案:

答案 0 :(得分:3)

因此,您的代码基本上可行 - 如果您使用与文件格式规范的作者使用相同的编译器和O / S(32位Windows)进行编译。您希望您的编译器完全根据您需要匹配文件字节来布局您的结构。例如,我可以在win32上编译并运行它并完美地读取WAV文件 - 直到标题的可变部分,其可变性无法编码。

编写了大量代码来操作各种文件格式后,我建议你放弃尝试读取结构,而是为“读取下4个字节并将它们转换为”等内容制作一些简单的实用函数一个int“。

请注意“额外格式字节”之类的内容。文件格式的一部分取决于文件格式的前几部分中的值。这就是为什么你通常需要把它看作一个动态的阅读过程,而不是一个大的阅读来抓住标题。保持结果高度可移植的C并不难以在操作系统之间工作而不依赖于诸如stat()之类的O / S特定事物或为htonl()之类的事物添加库依赖性 - 应该是可移植性(甚至可移植到不同的编译器或甚至只需要在同一个O / S上使用不同的编译器选项。

答案 1 :(得分:0)

您似乎注意到了endian问题,但处理它的方法是使用htonlntohlhtonsntohs。这是您的号码问题的一部分。

请阅读:

http://www.beej.us/guide/bgnet/output/html/multipage/htonsman.html

请注意,WAV文件中有很多其他帖子。你考虑过阅读吗?

此外,有一些标准方法可以通过Windows上的Windows API或linux / unix上的stat获取文件信息,例如大小。