X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=blobdiff_plain;f=lib%2Fwav.c;h=5bd30d7921fdb3fec1e89e2bc7923f505c2363bd;hp=1d6c67a97c823ea63f41359523e95b181058cc07;hb=2c719855eac434f01d47ba0717d76de65939d74e;hpb=96f6f939bc6a9cf64967842d5e13f949110b2d22 diff --git a/lib/wav.c b/lib/wav.c index 1d6c67a..5bd30d7 100644 --- a/lib/wav.c +++ b/lib/wav.c @@ -25,7 +25,7 @@ #include "wav.h" struct WAVBlock { - char id[4]; + char id[5]; unsigned int size; }; @@ -35,6 +35,7 @@ int getWAVBlock(FILE*fi, struct WAVBlock*block) unsigned char b[4]; if(fread(block->id,1,4,fi)<4) return 0; + block->id[4] = 0; if(fread(b,1,4,fi)<4) return 0; block->size = b[0]|b[1]<<8|b[2]<<16|b[3]<<24; @@ -45,15 +46,16 @@ int getWAVBlock(FILE*fi, struct WAVBlock*block) return 1; } -int readWAV(char* filename, struct WAV*wav) +int wav_read(struct WAV*wav, const char* filename) { FILE*fi = fopen(filename, "rb"); unsigned char b[16]; long int filesize; struct WAVBlock block; long int pos; + if(!fi) - return 0; + return 0; fseek(fi, 0, SEEK_END); filesize = ftell(fi); fseek(fi, 0, SEEK_SET); @@ -61,59 +63,93 @@ int readWAV(char* filename, struct WAV*wav) //printf("Filesize: %d\n", filesize); if(!getWAVBlock (fi, &block)) - return 0; - if(strncmp(block.id,"RIFF",4)) { - fprintf(stderr, "readWAV: not a WAV file\n"); - return 0; + { + fclose(fi); + return 0; + } + if(strncmp(block.id,"RIFF",4)) + { + fprintf(stderr, "wav_read: not a WAV file\n"); + fclose(fi); + return 0; } if(block.size + 8 < filesize) - fprintf(stderr, "readWAV: warning - more tags (%d extra bytes)\n", - filesize - block.size - 8); + fprintf(stderr, "wav_read: warning - more tags (%lu extra bytes)\n", filesize - block.size - 8); + + if(block.size == filesize) + /* some buggy software doesn't generate the right tag length */ + block.size = filesize - 8; + if(block.size + 8 > filesize) - fprintf(stderr, "readWAV: warning - short file (%d bytes missing)\n", - block.size + 8 - filesize); - if(fread(b, 1, 4, fi) < 4) { - return 0; - } - if(strncmp(b, "WAVE", 4)) { - fprintf(stderr, "readWAV: not a WAV file (2)\n"); - return 0; - } - - do + fprintf(stderr, "wav_read: warning - short file (%lu bytes missing)\n", block.size + 8 - filesize); + if(fread(b, 1, 4, fi) < 4) { - getWAVBlock(fi, &block); - pos = ftell(fi); - if(!strncmp(block.id, "fmt ", 4)) { - if(fread(&b, 1, 16, fi)<16) + fclose(fi); return 0; - wav->tag = b[0]|b[1]<<8; - wav->channels = b[2]|b[3]<<8; - wav->sampsPerSec = b[4]|b[5]<<8|b[6]<<16|b[7]<<24; - wav->bytesPerSec = b[8]|b[9]<<8|b[10]<<16|b[11]<<24; - wav->align = b[12]|b[13]<<8; - wav->bps = b[14]|b[15]<<8; - } else if (!strncmp(block.id, "LIST", 4)) { - // subchunk ICMT (comment) may exist - } else if (!strncmp(block.id, "data", 4)) { - wav->data = malloc(block.size); - if(!wav->data) { - fprintf(stderr, "Out of memory (%d bytes needed)", block.size); - return 0; - } - if(fread(wav->data, 1, block.size, fi) < block.size) + } + if(strncmp((const char*)b, "WAVE", 4)) + { + fprintf(stderr, "wav_read: not a WAV file (2)\n"); + fclose(fi); return 0; - wav->size = block.size; } - pos+=block.size; - fseek(fi, pos, SEEK_SET); + + do + { + getWAVBlock(fi, &block); + pos = ftell(fi); + if(!strncmp(block.id, "fmt ", 4)) + { + if(fread(&b, 1, 16, fi)<16) + { + fclose(fi); + return 0; + } + wav->tag = b[0]|b[1]<<8; + wav->channels = b[2]|b[3]<<8; + wav->sampsPerSec = b[4]|b[5]<<8|b[6]<<16|b[7]<<24; + wav->bytesPerSec = b[8]|b[9]<<8|b[10]<<16|b[11]<<24; + wav->align = b[12]|b[13]<<8; + wav->bps = b[14]|b[15]<<8; + } + else + if (!strncmp(block.id, "LIST", 4)) + { + // subchunk ICMT (comment) may exist + } + else + if (!strncmp(block.id, "data", 4)) + { + int l; + wav->data = (unsigned char*)malloc(block.size); + if(!wav->data) + { + fprintf(stderr, "Out of memory (%d bytes needed)", block.size); + fclose(fi); + return 0; + } + l = fread(wav->data, 1, block.size, fi); + if(l<=0) { + fprintf(stderr, "Error: Couldn't read WAV data block\n"); + fclose(fi); + return 0; + } else if(l < block.size) + { + fprintf(stderr, "Warning: data block of size %d is only %d bytes (%d bytes missing)\n", block.size, l, block.size-l); + wav->size = l; + } else { + wav->size = block.size; + } + } + pos+=block.size; + fseek(fi, pos, SEEK_SET); } while (pos < filesize); - + fclose(fi); return 1; } -int writeWAV(char*filename, struct WAV*wav) +int wav_write(struct WAV*wav, const char*filename) { FILE*fi = fopen(filename, "wb"); char*b="RIFFWAVEfmt \x10\0\0\0data"; @@ -158,14 +194,14 @@ int writeWAV(char*filename, struct WAV*wav) return 1; } -void printWAVInfo(struct WAV*wav) +void wav_print(struct WAV*wav) { - printf("tag:%04x channels:%d samples/sec:%d bytes/sec:%d align:%d bits/sample:%d size:%d\n", + printf("tag:%04x channels:%d samples/sec:%lu bytes/sec:%lu align:%d bits/sample:%d size:%d\n", wav->tag, wav->channels, wav->sampsPerSec, wav->bytesPerSec, wav->align, wav->bps, wav->size); } -int convertWAV2mono(struct WAV*src, struct WAV*dest, int rate) +int wav_convert2mono(struct WAV*src, struct WAV*dest, int rate) { int samplelen=src->size/src->align; int bps=src->bps; @@ -248,6 +284,8 @@ int convertWAV2mono(struct WAV*src, struct WAV*dest, int rate) pos += ratio; } } + } else { + fprintf(stderr, "Unsupported bitspersample value: %d\n", bps); } return 1; }