2013-02-19 1 views
2

Мне нужно прочитать переменные заголовка из волнового файла и показать, каковы они. Я использую следующий код, но мой вывод имеет слишком большие номера. Я искал решения в течение нескольких часов. Помощь будет очень признательна! Благодарю. Я получил формат волны SoundFile от https://ccrma.stanford.edu/courses/422/projects/WaveFormat/Код для чтения файла заголовка Wav, создающего странные результаты? C

Выход: 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

Операционная система? –

+0

И, если вы собираетесь полагаться на конкретный макет структур в памяти, нам также нужно знать, какой компилятор и какие параметры вы планируете использовать для его компиляции. –

+0

Операционная система UNIX с использованием gcc, все остальное отключено –

ответ

3

Таким образом, ваш код в основном работает - если вы скомпилировать его с тем же компилятор и O/S, которые использовал автор спецификации формата файла (32-разрядная версия Windows). Вы надеетесь, что ваш компилятор выложил вашу структуру точно так, как вам нужно, чтобы соответствовать байтам файла. Например, я могу скомпилировать и запустить его на win32 и отлично прочитать WAV-файл - вплоть до переменной части заголовка, чья изменчивость вам не удалось выполнить.

Написав много кода для управления различными форматами файлов, я бы посоветовал вам отказаться от попытки чтения в структуры и вместо этого сделать несколько простых служебных функций для таких вещей, как «читать следующие 4 байта и повернуть их в int ".

Обратите внимание на такие вещи, как «байты дополнительного формата». Части формата файла зависят от значений в предыдущих частях формата файла. Вот почему вам обычно нужно думать об этом как о динамическом процессе чтения, а не о большом чтении, чтобы захватить заголовки. Нетрудно сохранить результат очень переносимым C, который будет работать между операционными системами, не полагаясь на специфические вещи O/S, такие как stat() или добавляя зависимости библиотек для таких вещей, как htonl() - должна быть переносимость (даже переносимость к другому компилятору или даже просто разные параметры компилятора на одном и том же O/S).

+0

Спасибо! Проливает много понимания –

0

Похоже, вы заметили Endian проблему, но способ справиться именно с htonl , ntohl, htons, и, ntohs. Это часть вашей проблемы с номером.

Читайте здесь:

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

Примечание Есть много других сообщений здесь WAV файлов. Рассматривали ли вы их чтение?

Кроме того, существуют стандартные способы, чтобы получить информацию о файле, как размер, либо через API окон на окнах или stat на Linux/Unix

+0

Зачем препятствовать довольно переносимому способу получения размера файла, такого как ftell()? –

+0

Да, это метод. Предоставляется. Но если это так удобно, то почему stat() написал? Поскольку метаданные файлов больше, чем количество байтов в файле. –

+0

Спасибо, я думаю, что это поставило меня в правильном направлении. Я посмотрю на это больше. –