我需要从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;
}`
答案 0 :(得分:3)
因此,您的代码基本上可行 - 如果您使用与文件格式规范的作者使用相同的编译器和O / S(32位Windows)进行编译。您希望您的编译器完全根据您需要匹配文件字节来布局您的结构。例如,我可以在win32上编译并运行它并完美地读取WAV文件 - 直到标题的可变部分,其可变性无法编码。
编写了大量代码来操作各种文件格式后,我建议你放弃尝试读取结构,而是为“读取下4个字节并将它们转换为”等内容制作一些简单的实用函数一个int“。
请注意“额外格式字节”之类的内容。文件格式的一部分取决于文件格式的前几部分中的值。这就是为什么你通常需要把它看作一个动态的阅读过程,而不是一个大的阅读来抓住标题。保持结果高度可移植的C并不难以在操作系统之间工作而不依赖于诸如stat()之类的O / S特定事物或为htonl()之类的事物添加库依赖性 - 应该是可移植性(甚至可移植到不同的编译器或甚至只需要在同一个O / S上使用不同的编译器选项。
答案 1 :(得分:0)
您似乎注意到了endian问题,但处理它的方法是使用htonl
,ntohl
,htons
和ntohs
。这是您的号码问题的一部分。
请阅读:
http://www.beej.us/guide/bgnet/output/html/multipage/htonsman.html
请注意,WAV文件中有很多其他帖子。你考虑过阅读吗?
此外,有一些标准方法可以通过Windows上的Windows API或linux / unix上的stat
获取文件信息,例如大小。