/*---------------------------------------------------------------------------- .WAV file dumper Chris Giese http://SisAndHappy.com/ChrisGiese This code is public domain (no copyright). You can do whatever you want with it. 14 Jul 2011: new read_le16() and read_le32() 28 Mar 2008: first release ----------------------------------------------------------------------------*/ #include #include /****************************************************************************/ static unsigned read_le16(const void *buf0) { const unsigned char *buf = buf0; unsigned rv; rv = buf[1]; rv <<= 8; rv |= buf[0]; return rv; } /****************************************************************************/ static unsigned long read_le32(const void *buf0) { const unsigned char *buf = buf0; unsigned long rv; rv = buf[3]; rv <<= 8; rv |= buf[2]; rv <<= 8; rv |= buf[1]; rv <<= 8; rv |= buf[0]; return rv; } /****************************************************************************/ #define BPERL 16 /* byte/line for dump */ static void dump(const void *data0, unsigned count) { const unsigned char *data = data0; unsigned j, k; while(count != 0) { for(j = 0; j < BPERL; j++) { if(count == 0) break; printf("%02X ", data[j]); count--; } printf("\t"); for(k = 0; k < j; k++) { if(data[k] < ' ') printf("."); else printf("%c", data[k]); } printf("\n"); data += BPERL; } } /****************************************************************************/ int main(int arg_c, char *arg_v[]) { unsigned long pos, len; unsigned char buf[16]; FILE *f; if(arg_c != 2) { printf(".WAV file dumper\n"); return 1; } if((f = fopen(arg_v[1], "rb")) == NULL) { printf("Error: can't open file '%s'\n", arg_v[1]); return 2; } fseek(f, 0, SEEK_END); len = ftell(f); fseek(f, 0, SEEK_SET); if(fread(buf, 1, 12, f) != 12) NOT: { printf("Error: file '%s' is not a .WAV file\n", arg_v[1]); fclose(f); return 3; } if(memcmp(&buf[0], "RIFF", 4) || memcmp(&buf[8], "WAVE", 4)) goto NOT; printf("\nFile '%s': length from OS=%lu\n", arg_v[1], len); len = read_le32(&buf[4]); printf("Data length from file headers=%lu\n", len); while(1) { if(fread(buf, 1, 8, f) != 8) break; pos = ftell(f); len = read_le32(&buf[4]); printf("'%-4.4s' block: file offset=%lu, length=%lu\n", buf, pos, len); if(!memcmp(&buf[0], "fmt ", 4)) { unsigned long i; unsigned j; if(fread(buf, 1, 16, f) != 16) ERR: { printf("Error: unexpected end of .WAV " "file '%s'\n", arg_v[1]); fclose(f); return 3; } printf("\tcodec=0x%X\n", read_le16(&buf[0])); printf("\tnum channels=%u\n", read_le16(&buf[2])); printf("\tsamples/sec=%lu\n", read_le32(&buf[4])); printf("\tavg. bytes/sec=%lu\n",read_le32(&buf[8])); printf("\tblock align=%u\n", read_le16(&buf[12])); printf("\tbits/sample=%u\n", read_le16(&buf[14])); for(i = 16; i < len; ) { j = (len - i < 16) ? (unsigned)(len - i) : 16; if(fread(buf, 1, j, f) != j) goto ERR; dump(buf, j); i += j; } } fseek(f, pos + len, SEEK_SET); } fclose(f); return 0; }