/* rw_wav.c read and write .wav files not working for all .wav files */ #include #include #include "rw_wav.h" #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) void read_wave(char* file_name, header *w, char sound[]) { int i; FILE * inp; int sread; char sbyte; /* byte of sound */ int ibyte; short tbyte; int smin; int smax; int savg; int bad; /* flags bad data in read */ int nbread; /* number of bytes read */ int xtra; /* nbytes> 16 */ char cxtra[32]; int soundi; inp = fopen(file_name, "rb"); if(inp == NULL) { printf("can not open %s for reading. \n", file_name); exit(1); } printf("reading %s \n", file_name); sread = fread(&w->riff[0], 1, 4, inp); printf("first 4 bytes should be RIFF, <%c%c%c%c>\n", w->riff[0], w->riff[1], w->riff[2], w->riff[3]); sread = fread(&w->fsize, 1, 4, inp); printf("file has %d +8 bytes \n", w->fsize); sread = fread(&w->wave[0], 1, 4, inp); printf("should be WAVE, <%c%c%c%c>\n", w->wave[0], w->wave[1], w->wave[2], w->wave[3]); sread = fread(&w->fmt[0], 1, 4, inp); printf("should be fmt, <%c%c%c%c>\n", w->fmt[0], w->fmt[1], w->fmt[2], w->fmt[3]); sread = fread(&w->nbytes, 1, 4, inp); printf("block has %d bytes \n", w->nbytes); xtra = w-> nbytes-16; sread = fread(&w->ccode, 1, 2, inp); printf("compression code = %d \n", w->ccode); sread = fread(&w->channels, 1, 2, inp); printf("channels = %d \n", w->channels); sread = fread(&w->rate, 1, 4, inp); printf("rate = %d \n", w->rate); sread = fread(&w->avgrate, 1, 4, inp); printf("avg rate = %d \n", w->avgrate); sread = fread(&w->blockalign, 1, 2, inp); printf("blockalign = %d \n", w->blockalign); sread = fread(&w->bps, 1, 2, inp); printf("bits per sample = %d \n", w->bps); if(xtra>0) { sread = fread(&cxtra[0], 1, xtra, inp); w->nbytes = 16; } sread = fread(&w->data[0], 1, 4, inp); printf("should be data, <%c%c%c%c>\n", w->data[0], w->data[1], w->data[2], w->data[3]); if(w->data[0]!='d') { printf("unable to read this format.\n"); exit(1); } sread = fread(&w->csize, 1, 4, inp); printf("chunk size, csize %d \n", w->csize); if(w->csize<=0) { printf("unable to read this format.\n"); exit(1); } nbread = 44+xtra; printf("%d bytes read so far \n", nbread); bad = 0; savg = 0; soundi = 0; /* sound index, in case channels==2 */ for(i=0; icsize/w->channels; i++) { if(w->bps==8) { sread = fread(&sbyte, 1, 1, inp); if(sread != 1 && bad==0) { bad=1; printf("no read on byte %d \n", i); } sound[soundi] = sbyte; soundi++; if(w->channels==2) sread = fread(&sbyte, 1, 1, inp); /* only use one */ } else /* should be 16, 2 bytes */ { sread = fread(&tbyte, 1, 2, inp); if(sread != 2 && bad==0) { bad=1; printf("no read on byte %d \n", i); } sound[soundi] = tbyte/128; /* process as 8 bit */ soundi++; if(w->channels==2) sread = fread(&tbyte, 1, 2, inp); /* only use one */ } ibyte = sbyte; savg = savg + ibyte; if(i==0) {smin=ibyte; smax=ibyte;} smin = ibytesmax?ibyte:smax; if(i<10 || i>w->csize-10) printf("sound byte %d = %X %d int= %d \n", i, sbyte, sbyte, ibyte); } w->bps = 8; /* process as 8 bit, 1 channel */ if(w->channels==2) { w->csize = w->csize/w->channels; w->channels = 1; } printf("finished reading csize=%d bytes \n", w->csize); fflush(stdout); savg = savg / (int)w->csize; printf("smin=%d, smax=%d, savg=%d \n", smin, smax, savg); nbread = nbread+w->csize; printf("%d bytes read \n", nbread); fflush(stdout); /* not reading remaining chunks */ fclose(inp); printf("read_wav done. %s file read \n", file_name); fflush(stdout); } /* end read_wav */ void write_wave(char* file_name, header w, char sound[]) { int i; FILE * outp; /* .wav */ int sread, swrite; char sbyte; /* byte of sound */ int ibyte; char more[4]; int smin; int smax; int savg; int bad; /* flags bad data in read */ int nbread; /* number of bytes read */ printf("write_wav running to write %s \n", file_name); if(w.riff[0]!='R' || w.riff[1]!='I') { printf("invalid header structure, bye \n"); exit(1); } outp = fopen(file_name, "wb"); if(outp == NULL) { printf("can not open %s for writing. \n", file_name); exit(1); } printf("writing %s \n", file_name); swrite = fwrite(&w.riff[0], 1, 4, outp); printf("first 4 bytes should be RIFF, <%c%c%c%c>\n", w.riff[0],w.riff[1],w.riff[2],w.riff[3]); swrite = fwrite(&w.fsize, 1, 4, outp); printf("file has %d +8 bytes \n", w.fsize); swrite = fwrite(&w.wave[0], 1, 4, outp); printf("should be WAVE, <%c%c%c%c>\n", w.wave[0],w.wave[1],w.wave[2],w.wave[3]); swrite = fwrite(&w.fmt[0], 1, 4, outp); printf("should be fmt, <%c%c%c%c>\n",w.fmt[0],w.fmt[1],w.fmt[2],w.fmt[3]); swrite = fwrite(&w.nbytes, 1, 4, outp); printf("block has %d bytes \n", w.nbytes); swrite = fwrite(&w.ccode, 1, 2, outp); printf("compression code = %d \n", w.ccode); swrite = fwrite(&w.channels, 1, 2, outp); printf("channels = %d \n", w.channels); swrite = fwrite(&w.rate, 1, 4, outp); printf("rate = %d \n", w.rate); swrite = fwrite(&w.avgrate, 1, 4, outp); printf("avg rate = %d \n", w.avgrate); swrite = fwrite(&w.blockalign, 1, 2, outp); printf("blockalign = %d \n", w.blockalign); swrite = fwrite(&w.bps, 1, 2, outp); printf("bits per sample = %d \n", w.bps); swrite = fwrite(&w.data[0], 1, 4, outp); printf("should be data, <%c%c%c%c>\n", w.data[0],w.data[1],w.data[2],w.data[3]); swrite = fwrite(&w.csize, 1, 4, outp); printf("chunk size %d \n", w.csize); nbread = 44; printf("%d bytes written so far \n", nbread); bad = 0; savg = 0; for(i=0; iw.csize-10) printf("sound byte %d = %X %d \n", i, sbyte, sbyte); swrite = fwrite(&sbyte, 1, 1, outp); ibyte = sbyte; savg = savg + ibyte; if(i==0) {smin=ibyte; smax=ibyte;} smin = ibytesmax?ibyte:smax; } savg = savg / w.csize; printf("smin=%d, smax=%d, savg=%d \n", smin, smax, savg); nbread = nbread+w.csize; printf("%d bytes written so far \n", nbread); /* not copying remaining chunks */ fflush(outp); fclose(outp); printf("write_wav done. new %s file written \n", file_name); } /* end write_wav */ /* may need to rescale into -127 .. 127 */ void rescale(int n, float zn[]) /* only rescale real part */ { int i; float zmin, zmax, zavg; float sca, offs; zavg = 0.0; for(i=0; i-129.0) return; zavg = zavg/(float)n; printf("zmin=%f, zmax=%f, zavg=%f \n", zmin, zmax, zavg); sca = (zmax-zmin)/254.0; /* -127 to +127 */ offs = (zmax+zmin)/2.0; printf("scale=%f, offset=%f \n", sca, offs); for(i=0; i