home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************
- * NAME : fromwav
- * DESCRIPTION : converts wave file to compressed pcm
- * INPUT : options: filename [d] [a] [m] [w]
- * : filename input file name preffix[.suffix]
- * : d adpcm encode - default
- * : a alaw encode
- * : m mulaw encode
- * : w extended wave header unwrap
- * OUTPUT : file "preffix.vox"
- * RETURNS : none
- * NOTE : written with microsoft c7.0, thus the extra _'s
- * : on the compiler defines, use the oldnames library
- * : to avoid the same problem with the functions
- ****************************************************************/
-
- /* standard headers */
- #include <string.h>
- #include <ctype.h>
- #include <conio.h>
- #include <stdlib.h>
- #include <process.h>
- #include <stdio.h>
- #include <fcntl.h>
- #include <io.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- /* step size index shift table */
- int indsft[8]={-1, -1, -1, -1, 2, 4, 6, 8};
- /* step size table
- stpsz[i]=floor[16*(11/10)^i] */
- int stpsz[49]=
- {16,17,19,21,23,25,28,31,34,37,41,45,50,55,60,66,73,80,88,
- 97,107,118,130,143,157,173,190,209,230,253,279,307,337,371,
- 408,449,494,544,598,658,724,796,876,963,1060,1166,1282,1411,
- 1552};
- /* nibble to bit map */
- int nbl2bit[16][4]={
- {1,0,0,0},{1,0,0,1},{1,0,1,0},{1,0,1,1},{1,1,0,0},{1,1,0,1},
- {1,1,1,0},{1,1,1,1},{-1,0,0,0},{-1,0,0,1},{-1,0,1,0},{-1,0,1,1},
- {-1,1,0,0},{-1,1,0,1},{-1,1,1,0},{-1,1,1,1}};
- /* step size index */
- int ssindex=0;
- /* the current pcm signal */
- int signal=0;
- /* total length decoded */
- long total=0;
- /* length of the current read buffer */
- long length;
- /* offset into the current read buffer */
- long offset;
- /* nibble of the byte */
- int nibble;
- /* read buffer */
- int readbuf[8192];
- /* write buffer */
- unsigned char writebuf[8192];
- /* encode method: 0 -> adpcm, 1 -> mulaw, 2 -> alaw */
- int law=0;
- /* unwrap only flag */
- int unwrap=0;
- /* input & output file handles */
- int ifh,ofh;
- /* wave file format */
- int format;
- /* wave mode stero - mono */
- int mode;
- /* sample rate */
- long srate;
- /* somewhere to put stuff we ignore */
- int dummy[8];
- void errorout();
- int decode(unsigned char);
- unsigned char adpcm(int);
- unsigned char mulaw(int);
- unsigned char alaw(int);
- /****************************************************************
- * NAME : main(argc,argv)
- * DESCRIPTION : entrypoint to application
- * INPUT : options: filename [d] [a] [m] [w]
- * : filename input file name preffix[.suffix]
- * : d adpcm encode - default
- * : a alaw encode
- * : m mulaw encode
- * : w unwrap extended wave header
- * OUTPUT : none
- * RETURNS : none
- ****************************************************************/
- int main (int argc,char *argv[])
- {
- int argn; /* argument index */
- unsigned char ensig;
- int slth,sidx; /* string hacking variables */
- char oname[12];
- int yeanea;
- /* wellllll, we really do need input data */
- if(argc<2){
- printf("\nNo input file\n\n");
- errorout();
- }
- /* honest we do */
- if((ifh=_open(argv[1],_O_RDONLY|_O_BINARY))<0){
- printf("\nInput file %s was not opened\n\n",argv[1]);
- errorout();
- }
- /* check the rest of the arguments*/
- if(argc>2){
- for(argn=2;argn<argc;++argn){
- switch(tolower(*argv[argn])){
- case 'd': /* adpcm encode */
- law=0;
- break;
- case 'm':
- law=1; /* mulaw encode */
- break;
- case 'a':
- law=2; /* alaw encode */
- break;
- case 'w':
- unwrap=1; /* unwrap */
- break;
- default:
- printf("\nUnknown Option - %c\n\n",*argv[argn]);
- errorout();
- }
- }
- }
- /* lets see if we can deal with this input file */
- if(_read(ifh,&length,4)!=4){
- printf("bad input file\n");
- errorout();
- }
- if(length!=0x46464952){ /* 'RIFF' */
- printf("Not a riff file\n");
- errorout();
- }
- if(_read(ifh,&length,4)!=4){
- printf("bad input file\n");
- errorout();
- }
- if(_read(ifh,&length,4)!=4){
- printf("bad input file\n");
- errorout();
- }
- if(length!=0x45564157){ /* 'WAVE' */
- printf("Not a wave file\n");
- errorout();
- }
- if(_read(ifh,&length,4)!=4){
- printf("bad input file\n");
- errorout();
- }
- if(length!=0x20746d66){ /* 'fmt ' */
- printf("Bad wave file format\n");
- errorout();
- }
- if(_read(ifh,&length,4)!=4){
- printf("bad input file\n");
- errorout();
- }
- if(_read(ifh,&format,2)!=2){
- printf("bad input file\n");
- errorout();
- }
- if(!((length==16&&format==1)||(length==20&&format==16)||
- (length==18&&format==6)||(length==18&&format==7))){
- printf("Unreconize format block\n");
- errorout();
- }
- if(_read(ifh,&mode,2)!=2){
- printf("bad input file\n");
- errorout();
- }
- if(mode!=1){
- printf("Sorry mono files only\n");
- errorout();
- }
- if(_read(ifh,&srate,4)!=4){
- printf("bad input file\n");
- errorout();
- }
- if(srate!=6000&&srate!=8000){
- printf("Sorry sample rate must be 6000 or 8000 samples per second\n");
- errorout();
- }
- _read(ifh,dummy,(int)(length-8));
- if(_read(ifh,&length,4)!=4){
- printf("bad input file\n");
- errorout();
- }
- if(length!=0x61746164){ /* 'data' */
- printf("Bad wave file format\n");
- errorout();
- }
- if(_read(ifh,&length,4)!=4){
- printf("bad input file\n");
- errorout();
- }
- /* so far this looks like a usable wave file, lets get down to cases */
- if(format==1&&unwrap==1){
- printf("You must specify the compression method!\n");
- errorout();
- }
- if(format!=16&&format!=1&&law==0){
- printf("%s can not be made into adpcm file\n",argv[1]);
- errorout();
- }
- if(format!=7&&format!=1&&law==1){
- printf("%s can not be made into a-law file\n",argv[1]);
- errorout();
- }
- if(format!=6&&format!=1&&law==2){
- printf("%s can not be made into mu-law file\n",argv[1]);
- errorout();
- }
- /* build the output file name */
- strcpy(oname,argv[1]);
- slth=strlen(oname);
- /* get the prefix */
- for(sidx=0;sidx<slth;++sidx)
- if(oname[sidx]=='.')
- break;
- oname[sidx]=0; /* convert to asciz */
- strcat(oname,".vox"); /* tack on our suffix */
- /* opps, maybe */
- if((ofh=_open(oname,_O_RDONLY))>0){
- printf("output file %s already exits\n",oname);
- printf("Ok to replace (y or n)? ");
- yeanea=_getch();
- printf("%c\n",yeanea);
- if(yeanea=='y'||yeanea=='Y')
- _close(ofh);
- else
- errorout();
- }
- /* this should never happen */
- if((ofh=_open(oname,_O_WRONLY|_O_BINARY|_O_CREAT|_O_TRUNC,_S_IWRITE))<0){
- printf("output file %s not opened\n",oname);
- errorout();
- }
- length=8192;
- while(length==8192){
- length=_read(ifh,readbuf,16384)/2;
- if(unwrap==0)
- switch(law){
- case 0:
- for(offset=0;offset<length;++offset){
- ensig=(unsigned char)(adpcm(readbuf[offset]/16)*16);
- ++offset;
- ensig+=adpcm(readbuf[offset]/16);
- writebuf[offset/2]=ensig;
- }
- _write(ofh,writebuf,(short)(length/2));
- break;
- case 1:
- for(offset=0;offset<length;++offset){
- ensig=mulaw(readbuf[offset]/4);
- writebuf[offset]=ensig;
- }
- _write(ofh,writebuf,(short)(length));
- break;
- case 2:
- for(offset=0;offset<length;++offset){
- ensig=alaw(readbuf[offset]/8);
- writebuf[offset]=ensig;
- }
- _write(ofh,writebuf,(short)(length));
- break;
- }
- else
- _write(ofh,readbuf,(short)length);
- }
- _close(ifh);
- _close(ofh);
- return(0);
- }
- /****************************************************************
- * NAME : errorout()
- * DESCRIPTION : bad argument handler, prints usage header & exits
- * INPUT : none
- * OUTPUT : none
- * RETURNS : does not return, exits to dos
- ****************************************************************/
- void errorout()
- {
- printf("usage: fromwav filename [d] [a] [m]\n");
- printf(" filename - input file = prefix[.suffix]\n");
- printf(" output file = prefix.vox\n");
- printf(" NO indexed play files\n");
- printf(" d - default: adpcm encode\n");
- printf(" a - alaw encode\n m - mulaw encode\n");
- printf(" w - unwrap extended wave header\n");
- _close(ifh);
- _close(ofh);
- exit(0);
- }
- /****************************************************************
- * NAME : decode(encoded)
- * DESCRIPTION : does the actual adpcm decode
- * INPUT : the encoded nibble from the adpcm file
- * OUTPUT : the index into the step size table for the next encode
- * RETURNS : the encoded difference
- ****************************************************************/
- int decode(unsigned char encoded)
- {
- int diff,step;
- step=stpsz[ssindex];
- diff=nbl2bit[encoded][0]*(
- step*nbl2bit[encoded][1]+
- (step/2)*nbl2bit[encoded][2]+
- (step/4)*nbl2bit[encoded][3]+
- (step/8));
- ssindex=ssindex+indsft[(encoded%8)];
- if(ssindex<0)
- ssindex=0;
- if(ssindex>48)
- ssindex=48;
- return(diff);
- }
- unsigned char adpcm(int csig)
- {
- int diff,step;
- unsigned char encoded;
- step=stpsz[ssindex];
- if(csig>2047){
- csig=2047;
- printf("Input value exceeded +2047, value truncated\n");
- }
- if(csig<-2047){
- csig=-2047;
- printf("Input value exceeded -2047, value truncated\n");
- }
- diff=csig-signal;
- if(diff<0){
- encoded=8;
- diff=-diff;
- }
- else
- encoded=0;
- if(diff>=step){
- encoded+=4;
- diff-=step;
- }
- step/=2;
- if(diff>=step){
- encoded+=2;
- diff-=step;
- }
- step/=2;
- if(diff>=step)
- encoded+=1;
- signal+=decode(encoded);
- return(encoded);
- }
- unsigned char mulaw(int sig)
- {
- int sign;
- if(sig>0)
- sign=255;
- else{
- sig=-sig;
- sign=127;
- }
- if(sig<32)
- return((unsigned char)(sign-sig/2));
- if(sig<96)
- return((unsigned char)(sign-sig/4-8));
- if(sig<224)
- return((unsigned char)(sign-sig/8-20));
- if(sig<480)
- return((unsigned char)(sign-sig/16-34));
- if(sig<992)
- return((unsigned char)(sign-sig/32-49));
- if(sig<2016)
- return((unsigned char)(sign-(sig+32)/64-64));
- if(sig<4064)
- return((unsigned char)(sign-(sig+32)/128-80));
- if(sig<8160)
- return((unsigned char)(sign-(sig+32)/256-96));
- return((unsigned char)(sign-127));
- }
- unsigned char alaw(int sig)
- {
- int sign;
- if(sig<0){
- sig=-sig;
- sign=0;
- }
- else
- sign=128;
- if(sig<64)
- return((unsigned char)((sign+sig/2)^0x55));
- if(sig<128)
- return((unsigned char)((sign+sig/4+16)^0x55));
- if(sig<256)
- return((unsigned char)((sign+sig/8+32)^0x55));
- if(sig<512)
- return((unsigned char)((sign+sig/16+48)^0x55));
- if(sig<1024)
- return((unsigned char)((sign+sig/32+64)^0x55));
- if(sig<2048)
- return((unsigned char)((sign+sig/64+80)^0x55));
- if(sig<4096)
- return((unsigned char)((sign+sig/128+96)^0x55));
- return((unsigned char)((sign+127)^0x55));
- }
-