#include "wav.h"
struct WAVBlock {
- char id[4];
+ char id[5];
unsigned int size;
};
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;
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);
//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";
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;
pos += ratio;
}
}
+ } else {
+ fprintf(stderr, "Unsupported bitspersample value: %d\n", bps);
}
return 1;
}