Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Считывание заголовка WAV файла


Автор: ChinaUA 22.4.2012, 17:48
Доброго времени суток!
Есть задача считать заголовок WAV файла и представить данные в читабельной форме.
У меня есть вот такой вод код:

Код

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

typedef struct  WAV_HEADER
{
    char                RIFF[4];        /* RIFF Header      */ 
    unsigned long       ChunkSize;      /* RIFF Chunk Size  */
    char                WAVE[4];        /* WAVE Header      */
    char                fmt[4];         /* FMT header       */
    unsigned long       Subchunk1Size;  /* Size of the fmt chunk                                */
    unsigned short      AudioFormat;    // Audio format 1=PCM
    unsigned short      NumOfChan;      /* Number of channels 1=Mono 2=Sterio                   */
    unsigned long       SamplesPerSec;  /* Sampling Frequency in Hz                             */
    unsigned long       bytesPerSec;    /* bytes per second */
    unsigned short      blockAlign;     /* 2=16-bit mono, 4=16-bit stereo */
    unsigned short      bitsPerSample;  /* Number of bits per sample      */
    char                Subchunk2ID[4]; /* "Data"  string   */
    unsigned long       Subchunk2Size;  /* Sampled data length    */
}wav_hdr; 

/* Function prototypes */
int getFileSize(FILE *inFile); 
int main(int argc,char *argv[])
{
    wav_hdr wavHeader;
    FILE *wavFile;
    int headerSize = sizeof(wav_hdr),filelength = 0;
    wavFile = fopen("/WAV/welcome.wav","r");
    if(wavFile == NULL)
    {
        printf("Can not able to open wave file\n");
        exit(EXIT_FAILURE);
    }
    fread(&wavHeader,headerSize,1,wavFile);
    filelength = getFileSize(wavFile);
    fclose(wavFile);
    printf("File is %d bytes.\n",filelength);
    printf("RIFF header                           :%c%c%c%c\n",wavHeader.RIFF[0],wavHeader.RIFF[1],wavHeader.RIFF[2],wavHeader.RIFF[3]);
    printf("WAVE header                           :%c%c%c%c\n",wavHeader.WAVE[0],wavHeader.WAVE[1],wavHeader.WAVE[2],wavHeader.WAVE[3]);
    printf("FMT                                   :%c%c%c%c\n",wavHeader.fmt[0],wavHeader.fmt[1],wavHeader.fmt[2],wavHeader.fmt[3]);
    printf("Data size (based on bits used)        :%ld\n",wavHeader.ChunkSize);
    
    // Display the sampling Rate form the header
    printf("Sampling Rate                         :%ld\n",wavHeader.SamplesPerSec); //Sampling frequency of the wav file
    printf("Number of bits used                   :%d\n",wavHeader.bitsPerSample); //Number of bits used per sample
    printf("Number of channels                    :%d\n",wavHeader.bitsPerSample);     //Number of channels (mono=1/sterio=2)
    printf("Number of bytes per second            :%ld\n",wavHeader.bytesPerSec);   //Number of bytes per second
    printf("Data length                           :%ld\n",wavHeader.Subchunk2Size);
    getchar();
} 
/* find the file size */
int getFileSize(FILE *inFile)
{
    int fileSize = 0;
    fseek(inFile,0,SEEK_END);
    fileSize=ftell(inFile);
    fseek(inFile,0,SEEK_SET);
    return fileSize;
}


В результате данные получаю частично корректные:
File is 260028 bytes.
RIFF header                           :RIFF
WAVE header                           :
FMT                                   :
Data size (based on bits used)        :2338614392529502551
Sampling Rate                         :259984
Number of bits used                   :1
Number of channels                    :1
Number of bytes per second            :0
Data length                           :562958543421441

Подскажите, что не так в коде. Программирую под Mac OS в Xcode...

Автор: feodorv 22.4.2012, 18:45
Цитата(ChinaUA @  22.4.2012,  18:48 Найти цитируемый пост)
Подскажите, что не так в коде.

Даже не знаю, что сказать. Или в Mac OS тоже нужно fopen(...,"rb"); (что вряд ли))), либо файл какой-то неправильный ;) Вы его каким-нибудь HEX-viewer'ом смотрели?

Откомпилил программу в виндах (с учётом исправления), запустил, получил:
Цитата

File is 58 bytes.
RIFF header                           :RIFF
WAVE header                           :WAVE
FMT                                   :fmt 
Data size (based on bits used)        :50
Sampling Rate                         :22050
Number of bits used                   :8
Number of channels                    :8
Number of bytes per second            :22050
Data length                           :291939

Автор: volatile 22.4.2012, 18:54
В таких вещах обязательно нужно прагма пак выставлять.

Автор: feodorv 22.4.2012, 19:06
Цитата(volatile @  22.4.2012,  19:54 Найти цитируемый пост)
В таких вещах обязательно нужно прагма пак выставлять. 

А ведь верно  smile А ещё проверить sizeof встроенных типов... Может, там long 64-битный...

Автор: volatile 22.4.2012, 19:17
Цитата(feodorv @  22.4.2012,  19:06 Найти цитируемый пост)
Может, там long 64-битный... 

Совершенно верно!
И даже не может, а он там точно 64-бытный.  smile 
Цитата(ChinaUA @  22.4.2012,  17:48 Найти цитируемый пост)
printf("Data size (based on bits used)        :%ld\n",wavHeader.ChunkSize);

Цитата(ChinaUA @  22.4.2012,  17:48 Найти цитируемый пост)
Data size (based on bits used)        :2338614392529502551

такое в 32 бита не влезет

Автор: ChinaUA 22.4.2012, 19:22
Спасибо за ответы, честно говоря в программировании новичек. Код взял готовый, пытаюсь в нем разобраться. Подскажите, если long 64 битный, как быть в данном ситуации? Прописать другой тип данных?

Автор: feodorv 22.4.2012, 19:29
Цитата(volatile @  22.4.2012,  20:17 Найти цитируемый пост)
такое в 32 бита не влезет

Да уж! А я даже не посмотрел(((

Цитата(ChinaUA @  22.4.2012,  20:22 Найти цитируемый пост)
Прописать другой тип данных? 

Можно попробовать простой int.
Но, главное, распечатать sizeof(wav_hdr), должно быть 44 smile 

Автор: ChinaUA 22.4.2012, 19:48
А как собственно распечатать sizeof(wav_hdr), если использовать printf() - ругается....
Поменял все переменные кроме char на int.
Результат лучше, но еще не идеальный))


File is 260028 bytes.
RIFF header                           :RIFF
WAVE header                           :WAVE
FMT                                   :fmt 
Data size (based on bits used)        :260020
Sampling Rate                         :176400
Number of bits used                   :259984
Number of channels                    :259984
Number of bytes per second            :1048580
Data length                           :0


Автор: feodorv 22.4.2012, 19:57
Цитата(ChinaUA @  22.4.2012,  20:48 Найти цитируемый пост)
А как собственно распечатать sizeof(wav_hdr), если использовать printf() - ругается....

Ну, эээ.
Код

printf( "Size of struct:        %u\n", sizeof(wav_hdr));


Цитата(ChinaUA @  22.4.2012,  20:48 Найти цитируемый пост)
Результат лучше, но еще не идеальный))

А печать идёт всё так же, через %ld?


Автор: ChinaUA 22.4.2012, 20:01
Цитата

printf( "Size of struct:        %u\n", sizeof(wav_hdr));


Спасибо, распечатал - 52... В чем же загвоздка...

Цитата

А печать идёт всё так же, через %ld?


Печать идет через %d

Автор: feodorv 22.4.2012, 20:17
Цитата(ChinaUA @  22.4.2012,  21:01 Найти цитируемый пост)
Спасибо, распечатал - 52... В чем же загвоздка...

Разница - 8 байт. Могу предположить, что виноваты short: либо sizeof(short) есть 4, либо каждое short (волевым решением компилятора) занимает 4 байта. Как указывал volatile:
Цитата(volatile @  22.4.2012,  19:54 Найти цитируемый пост)
В таких вещах обязательно нужно прагма пак выставлять. 


Проверить можно так:
Код

struct test
{
  unsigned short s1;
  unsigned short s2;
};

printf( "Short size %u, struct size %u\n", sizeof(short), sizeof(struct test));

Для правильной работы нужно 2 и 4 байта соответственно.

Как в МакОС выставлять прагма пак, я не знаю (возможно, что также как и в винде).

Цитата(ChinaUA @  22.4.2012,  21:01 Найти цитируемый пост)
Печать идет через %d 

 smile 

Автор: ChinaUA 22.4.2012, 20:27
Спасибо тебе огромное! Немного вроде наладилось. Хотел тебе плюсик поставить, постов не хватает...

Теперь результат вроде корректный

File is 260028 bytes.
RIFF header                           :RIFF
WAVE header                           :WAVE
FMT                                   :fmt 
Data size (based on bits used)        :260020
Sampling Rate                         :44100
Number of bits used                   :16
Number of channels                    :16
Number of bytes per second            :176400
Data length                           :259984

Вот только смущает Number of channels                    :16, насколько я понимаю тут должно быть либо 1 либо 2...

Добавлено через 9 минут и 59 секунд
Ой, тупанул, с Number of channels разобрался, продублировалась строка...

Теперь еще небольшой вопрос. Может сталкивался с проигрывание WAV с помощью PortAudio API?

Автор: feodorv 22.4.2012, 21:01
Цитата(ChinaUA @  22.4.2012,  21:27 Найти цитируемый пост)
Хотел тебе плюсик поставить, постов не хватает...

)))) Спасибо, volatile уже компенсировал  smile Ну когда всё успевает)))
На самом деле, плюсик нужно отнести нему ;)

Цитата(ChinaUA @  22.4.2012,  21:27 Найти цитируемый пост)
Теперь результат вроде корректный

Я рад)))

Цитата(ChinaUA @  22.4.2012,  21:27 Найти цитируемый пост)
Теперь еще небольшой вопрос. Может сталкивался с проигрывание WAV с помощью PortAudio API? 

А вот тут, увы, нечем помочь не могу...

Автор: ChinaUA 22.4.2012, 21:03
Спасибо и на этом!
Друзья, может кто-нибудь подскажет, как модно воспроизвести WAV под Mac OS?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)