读取wave文件信息,打印文件头各字段的内容,以及音频数据的二进制值。wave文件的音频数据可能是各种压缩采样格式的。

李国帅 2010


#include "stdio.h"
#include "stdlib.h"
#include "string.h"
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned long uint32;
typedef enum { false, true } boolean;
typedef struct
{
unsigned char chunkID[4]; // Contiene le lettere "RIFF" in formato ASCII form (0x52494646 formato big-endian)
unsigned int ChunkSize; // 36 + SubChunk2Size, o più precisamente:
// 4 + (8 + SubChunk1Size) + (8 + SubChunk2Size)
// Questa è la dimensione del resto del chunk che segue questo numero.Questa è la dimensione dell'intero file
// in bytes meno 8 bytes per i due campi non inclusi in queto conteggio
// ChunkID e ChunkSize.
unsigned char Format[4]; // Contiene le lettere "WAVE"(0x57415645 formato big-endian).
unsigned char Subchunk1ID[4]; // Contiene le lettere "fmt " (0x666d7420 formato big-endian).
unsigned int Subchunk1Size; // 16 for PCM. This is the size of the rest of the Subchunk which follows this number
short int AudioFormat; // PCM = 1 (i.e. Linear quantization)
// Values other than 1 indicate someform of compression.
short int NumChannels; // Mono = 1, Stereo += 2, etc.
int SampleRate; // 8000, 44100, etc.
int ByteRate; // = SampleRate * NumChannels * BitsPerSample/8
short int BlockAlign; // = NumChannels * BitsPerSample/8
// The number of bytes for one sample including all channels
short int BitsPerSample;// 8 bits += 8, 16 bits += 16, etc.
short int Extra;
unsigned char Data[4]; // Contains the letters "data" (0x64617461 big-endian form).
unsigned int DataSize; // = NumSamples * NumChannels * BitsPerSample/8 This is the number of bytes in the data.
} __attribute__((packed)) RIFF_HEADER;

boolean ispadded(RIFF_HEADER *header);
int main(int argc, char *argv[])
{
RIFF_HEADER *header;
FILE *fp;
int i;
int num_neg = 0;
int num_pos = 0;
short int c;
char *filename;
char *dati;
if (argc > 1)
{
printf("Lunghezza argv[1]: %d\n", strlen(argv[1]));
filename = (char *)(malloc(strlen(argv[1]) + 1));
strcpy(filename, argv[1]);
printf("Filename:%s\n", filename);
fp = fopen(filename, "rb");
}

header = (RIFF_HEADER *)malloc(sizeof(RIFF_HEADER));
printf("Header Size=%d\n", sizeof(RIFF_HEADER));
fread(header, sizeof(RIFF_HEADER), 1, fp);
printf("Is Padded %d\n", ispadded(header));
printf("ChunkID:%4.4s\n", header->chunkID);
printf("ChunkSize:%u\n", header->ChunkSize);
printf("Format:%4.4s\n", header->Format);
printf("Subchunk1ID:%4.4s\n", header->Subchunk1ID);
printf("Subchunk1Size:%u\n", header->Subchunk1Size);
printf("AudioFormat:%d\n", header->AudioFormat);
printf("NumChannels:%d\n", header->NumChannels);
printf("SampleRate:%d\n", header->SampleRate);
printf("ByteRate:%d\n", header->ByteRate);
printf("BlockAlign:%d\n", header->BlockAlign);
printf("BitsPerSample:%d\n", header->BitsPerSample);
printf("Extra:%d\n", header->Extra);
printf("Data:%4.4s\n", header->Data);
printf("DataSize:%u\n", (header->DataSize));
dati = (char *)malloc(header->DataSize + 1);
if (dati == NULL) printf("Errore. memoria insufficiente!\n");
i = 0;
//if (fread(dati,header->DataSize,1,fp)>0) printf("Lettura eseguita correttamente\n");
//else
//printf("Lettura non eseguita correttamente\n");
//printf("strlen(dati)=%d\n",strlen(dati));
//dati[strlen(dati)+1]='\0';
//printf("strlen(dati)=%d\n",strlen(dati));
//fread(&c,sizeof(int),1,fp);

while (fread(&c, sizeof(short int), 1, fp) > 0)
{
if (c > 0) num_pos++;
else
num_neg++;
printf("%hd\n", c);
}
printf("\n Neg:%d Pos:%d\n", num_neg, num_pos);
//while(*dati!='\0'){

//for (i=0;i<header->DataSize;i++)
//printf("\t i=%d dati=%d",i,dati[i]);
return 0;
}
boolean ispadded(RIFF_HEADER *header)
{
short int sizeofheaders = sizeof(RIFF_HEADER);
short int size_of_fields = 0;
size_of_fields += sizeof(header->chunkID);
size_of_fields += sizeof(header->ChunkSize);
size_of_fields += sizeof(header->Format);
size_of_fields += sizeof(header->Subchunk1ID);
size_of_fields += sizeof(header->Subchunk1Size);
size_of_fields += sizeof(header->AudioFormat);
size_of_fields += sizeof(header->NumChannels);
size_of_fields += sizeof(header->SampleRate);
size_of_fields += sizeof(header->ByteRate);
size_of_fields += sizeof(header->BlockAlign);
size_of_fields += sizeof(header->BitsPerSample);
size_of_fields += sizeof(header->Data);
size_of_fields += sizeof(header->DataSize);
size_of_fields += sizeof(header->Extra);
printf("Header size=%d fields size=%d\n", sizeofheaders, size_of_fields);
return (sizeofheaders == size_of_fields);
}