/* * Read RIFF header * spd@daphne.cps.unizar.es * Mon Jul 29 21:21:40 CEST 2002 */ #include #include #include #include #include #include #include #if defined(__i386__) || defined (_M_IX86) || defined (__osf__) # define LITTLEENDIAN #else # define BIGENDIAN #endif #define swap_word(a) ( ((a) << 24) | \ (((a) << 8) & 0x00ff0000) | \ (((a) >> 8) & 0x0000ff00) | \ ((unsigned long)(a) >>24) ) #define swap_half(a) ( ((a & 0xff) << 8) | ((unsigned short)(a) >> 8) ) #ifdef BIGENDIAN # define SWAP_WORD(a) { a = swap_word(a); } # define SWAP_HALF(a) { a = swap_half(a); } #else # define SWAP_WORD(a) # define SWAP_HALF(a) #endif /* */ typedef struct WAV_format { char riff[4]; /* the characters "RIFF" */ unsigned long file_length; /* file length - 8 */ char wave[8]; /* the characters "WAVEfmt " */ unsigned long offset; /* position of "data"-20 (usually 16) */ unsigned short format; /* 1 = PCM */ unsigned short nchans; /* #channels (eg. 2=stereo) */ unsigned long sampsec; /* #samples/sec (eg. 44100 for CD rate) */ unsigned long bytesec; /* #bytes/sec (see note 1) */ unsigned short bytesamp; /* #bytes/sample (see note 1) */ unsigned short bitsamp; /* #bits/sample (see note 1) */ /* char otherstuff[N]; /* N = offset-16 (see note 5) */ char *otherstuff; char dataheader[4]; /* the characters "data" */ unsigned long datalen; /* #bytes of actual data */ } wav_header; char *formats[256]={ /* 00 */ "unknown", "PCM", "MS ADPCM", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", /* 10 */ "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", /* 20 */ "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", /* 30 */ "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", /* 40 */ "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", /* 50 */ "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", /* 60 */ "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", /* 70 */ "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", /* 80 */ "unknown", "unknown", "unknown", "unknown", "unknown", "MP3", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown", "unknown" }; int main(int argc, char **argv) { #ifndef BS #define BS 512 #endif int i; int o; char buffer[BS]; struct stat sbp; size_t n; wav_header wav; assert (sizeof(long)==4); assert (sizeof(short)==2); if ( lstat(argv[1],&sbp)==-1) { perror("stat"); return 1; } printf("Size: %ld\n", sbp.st_size); printf("Head: %d\n", sizeof(wav_header)-4); if ( -1 == ( i = open( argv[1], O_RDONLY))) { perror("open"); return 1; } read( i, &wav, sizeof(wav_header)-12); SWAP_WORD(wav.file_length); SWAP_WORD(wav.offset); SWAP_HALF(wav.format); SWAP_HALF(wav.nchans); SWAP_WORD(wav.sampsec); SWAP_WORD(wav.bytesec); SWAP_HALF(wav.bytesamp); SWAP_HALF(wav.bitsamp); printf("riff: \"%.4s\"\n",wav.riff); printf("length: %lu\n",wav.file_length+8); printf("wave: \"%.8s\"\n",wav.wave); printf("offset: %lu\n",wav.offset); printf("format: %hu (%s)\n",wav.format, formats[wav.format]); printf("channels: %hu\n",wav.nchans); printf("samples/s: %lu\n",wav.sampsec); printf("bytes/s: %lu\n",wav.bytesec); printf("bytesamp: %hu\n",wav.bytesamp); printf("bitsamp: %hu\n",wav.bitsamp); /* char otherstuff[N]; /* N = offset-16 (see note 5) */ wav.otherstuff=buffer; n=0; if ( wav.offset != 16 ) { read( i, buffer, wav.offset - 4); printf("otherstuff:\"%s\"\n",wav.otherstuff); n=wav.offset - 4; } read( i, &wav.dataheader, 4); printf("datahead: \"%.4s\"\n",wav.dataheader); read( i, &wav.datalen, 4); SWAP_WORD(wav.datalen); printf("datalen: %lu\n",wav.datalen); printf("\n%d+%d+%lu=%lu (%lu)\n", sizeof(wav_header)-4, n, wav.datalen, sizeof(wav_header)-4 + n + wav.datalen, sbp.st_size ); close(i); }