home *** CD-ROM | disk | FTP | other *** search
/ PC Musician 2000 / PC_Musician_2000.iso / PCMUSIC / MISC / VOX2WAV / FROMWAVE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-06  |  10.7 KB  |  407 lines

  1. /****************************************************************
  2. *     NAME : fromwav
  3. * DESCRIPTION : converts wave file to compressed pcm
  4. *    INPUT : options:  filename [d] [a] [m] [w]
  5. *          : filename input file name preffix[.suffix]
  6. *          : d adpcm encode - default
  7. *          : a alaw encode
  8. *          : m mulaw encode
  9. *          : w extended wave header unwrap
  10. *      OUTPUT : file "preffix.vox"
  11. *     RETURNS : none
  12. *     NOTE : written with microsoft c7.0, thus the extra _'s
  13. *          : on the compiler defines, use the oldnames library
  14. *          : to avoid the same problem with the functions
  15. ****************************************************************/
  16.  
  17. /* standard headers */
  18. #include <string.h>
  19. #include <ctype.h>
  20. #include <conio.h>
  21. #include <stdlib.h>
  22. #include <process.h>
  23. #include <stdio.h>
  24. #include <fcntl.h>
  25. #include <io.h>
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28. /* step size index shift table */
  29. int indsft[8]={-1, -1, -1, -1, 2, 4, 6, 8};
  30. /* step size table
  31.     stpsz[i]=floor[16*(11/10)^i] */
  32. int stpsz[49]=
  33. {16,17,19,21,23,25,28,31,34,37,41,45,50,55,60,66,73,80,88,
  34. 97,107,118,130,143,157,173,190,209,230,253,279,307,337,371,
  35. 408,449,494,544,598,658,724,796,876,963,1060,1166,1282,1411,
  36. 1552};
  37. /* nibble to bit map */
  38. int nbl2bit[16][4]={
  39. {1,0,0,0},{1,0,0,1},{1,0,1,0},{1,0,1,1},{1,1,0,0},{1,1,0,1},
  40. {1,1,1,0},{1,1,1,1},{-1,0,0,0},{-1,0,0,1},{-1,0,1,0},{-1,0,1,1},
  41. {-1,1,0,0},{-1,1,0,1},{-1,1,1,0},{-1,1,1,1}};
  42. /* step size index */
  43. int ssindex=0;
  44. /* the current pcm signal */
  45. int signal=0;
  46. /* total length decoded */
  47. long total=0;
  48. /* length of the current read buffer */
  49. long length;
  50. /* offset into the current read buffer */
  51. long offset;
  52. /* nibble of the byte */
  53. int nibble;
  54. /* read buffer */
  55. int readbuf[8192];
  56. /* write buffer */
  57. unsigned char writebuf[8192];
  58. /* encode method: 0 -> adpcm, 1 -> mulaw, 2 -> alaw */
  59. int law=0;
  60. /* unwrap only flag */
  61. int unwrap=0;
  62. /* input & output file handles */
  63. int ifh,ofh;
  64. /* wave file format */
  65. int format;
  66. /* wave mode stero - mono */
  67. int mode;
  68. /* sample rate */
  69. long srate;
  70. /* somewhere to put stuff we ignore */
  71. int dummy[8];
  72. void errorout();
  73. int decode(unsigned char);
  74. unsigned char adpcm(int);
  75. unsigned char mulaw(int);
  76. unsigned char alaw(int);
  77. /****************************************************************
  78. *        NAME : main(argc,argv)
  79. * DESCRIPTION : entrypoint to application
  80. *    INPUT : options:  filename [d] [a] [m] [w]
  81. *          : filename input file name preffix[.suffix]
  82. *          : d adpcm encode - default
  83. *          : a alaw encode
  84. *          : m mulaw encode
  85. *          : w unwrap extended wave header
  86. *      OUTPUT : none
  87. *     RETURNS : none
  88. ****************************************************************/
  89. int main (int argc,char *argv[])
  90. {
  91. int argn;        /* argument index */
  92. unsigned char ensig;
  93. int slth,sidx;        /* string hacking variables */
  94. char oname[12];
  95. int yeanea;
  96.     /* wellllll, we really do need input data */
  97.     if(argc<2){
  98.     printf("\nNo input file\n\n");
  99.     errorout();
  100.     }
  101.     /* honest we do */
  102.     if((ifh=_open(argv[1],_O_RDONLY|_O_BINARY))<0){
  103.     printf("\nInput file %s was not opened\n\n",argv[1]);
  104.     errorout();
  105.     }
  106.     /* check the rest of the arguments*/
  107.     if(argc>2){
  108.     for(argn=2;argn<argc;++argn){
  109.         switch(tolower(*argv[argn])){
  110.         case 'd':        /* adpcm encode */
  111.             law=0;
  112.             break;
  113.         case 'm':
  114.             law=1;        /* mulaw encode */
  115.             break;
  116.         case 'a':
  117.             law=2;        /* alaw encode */
  118.             break;
  119.         case 'w':
  120.             unwrap=1;        /* unwrap */
  121.             break;
  122.     default:
  123.             printf("\nUnknown Option - %c\n\n",*argv[argn]);
  124.             errorout();
  125.         }
  126.     }
  127.     }
  128.     /* lets see if we can deal with this input file */
  129.     if(_read(ifh,&length,4)!=4){
  130.     printf("bad input file\n");
  131.     errorout();
  132.     }
  133.     if(length!=0x46464952){        /* 'RIFF' */
  134.     printf("Not a riff file\n");
  135.     errorout();
  136.     }
  137.     if(_read(ifh,&length,4)!=4){
  138.     printf("bad input file\n");
  139.     errorout();
  140.     }
  141.     if(_read(ifh,&length,4)!=4){
  142.     printf("bad input file\n");
  143.     errorout();
  144.     }
  145.     if(length!=0x45564157){        /* 'WAVE' */
  146.     printf("Not a wave file\n");
  147.     errorout();
  148.     }
  149.     if(_read(ifh,&length,4)!=4){
  150.     printf("bad input file\n");
  151.     errorout();
  152.     }
  153.     if(length!=0x20746d66){        /* 'fmt ' */
  154.     printf("Bad wave file format\n");
  155.     errorout();
  156.     }
  157.     if(_read(ifh,&length,4)!=4){
  158.     printf("bad input file\n");
  159.     errorout();
  160.     }
  161.     if(_read(ifh,&format,2)!=2){
  162.     printf("bad input file\n");
  163.     errorout();
  164.     }
  165.     if(!((length==16&&format==1)||(length==20&&format==16)||
  166.     (length==18&&format==6)||(length==18&&format==7))){
  167.     printf("Unreconize format block\n");
  168.     errorout();
  169.     }
  170.     if(_read(ifh,&mode,2)!=2){
  171.     printf("bad input file\n");
  172.     errorout();
  173.     }
  174.     if(mode!=1){
  175.     printf("Sorry mono files only\n");
  176.     errorout();
  177.     }
  178.     if(_read(ifh,&srate,4)!=4){
  179.     printf("bad input file\n");
  180.     errorout();
  181.     }
  182.     if(srate!=6000&&srate!=8000){
  183.     printf("Sorry sample rate must be 6000 or 8000 samples per second\n");
  184.     errorout();
  185.     }
  186.     _read(ifh,dummy,(int)(length-8));
  187.     if(_read(ifh,&length,4)!=4){
  188.     printf("bad input file\n");
  189.     errorout();
  190.     }
  191.     if(length!=0x61746164){        /* 'data' */
  192.     printf("Bad wave file format\n");
  193.     errorout();
  194.     }
  195.     if(_read(ifh,&length,4)!=4){
  196.     printf("bad input file\n");
  197.     errorout();
  198.     }
  199.     /* so far this looks like a usable wave file, lets get down to cases */
  200.     if(format==1&&unwrap==1){
  201.     printf("You must specify the compression method!\n");
  202.     errorout();
  203.     }
  204.     if(format!=16&&format!=1&&law==0){
  205.     printf("%s can not be made into adpcm file\n",argv[1]);
  206.     errorout();
  207.     }
  208.     if(format!=7&&format!=1&&law==1){
  209.     printf("%s can not be made into a-law file\n",argv[1]);
  210.     errorout();
  211.     }
  212.     if(format!=6&&format!=1&&law==2){
  213.     printf("%s can not be made into mu-law file\n",argv[1]);
  214.     errorout();
  215.     }
  216.     /* build the output file name */
  217.     strcpy(oname,argv[1]);
  218.     slth=strlen(oname);
  219.     /* get the prefix */
  220.     for(sidx=0;sidx<slth;++sidx)
  221.     if(oname[sidx]=='.')
  222.         break;
  223.     oname[sidx]=0;        /* convert to asciz */
  224.     strcat(oname,".vox");   /* tack on our suffix */
  225.     /* opps, maybe */
  226.     if((ofh=_open(oname,_O_RDONLY))>0){
  227.     printf("output file %s already exits\n",oname);
  228.     printf("Ok to replace (y or n)? ");
  229.     yeanea=_getch();
  230.     printf("%c\n",yeanea);
  231.     if(yeanea=='y'||yeanea=='Y')
  232.         _close(ofh);
  233.     else
  234.         errorout();
  235.     }
  236.     /* this should never happen */
  237.     if((ofh=_open(oname,_O_WRONLY|_O_BINARY|_O_CREAT|_O_TRUNC,_S_IWRITE))<0){
  238.     printf("output file %s not opened\n",oname);
  239.     errorout();
  240.     }
  241.     length=8192;
  242.     while(length==8192){
  243.     length=_read(ifh,readbuf,16384)/2;
  244.     if(unwrap==0)
  245.         switch(law){
  246.         case 0:
  247.             for(offset=0;offset<length;++offset){
  248.             ensig=(unsigned char)(adpcm(readbuf[offset]/16)*16);
  249.             ++offset;
  250.             ensig+=adpcm(readbuf[offset]/16);
  251.             writebuf[offset/2]=ensig;
  252.             }
  253.             _write(ofh,writebuf,(short)(length/2));
  254.             break;
  255.         case 1:
  256.             for(offset=0;offset<length;++offset){
  257.             ensig=mulaw(readbuf[offset]/4);
  258.             writebuf[offset]=ensig;
  259.             }
  260.             _write(ofh,writebuf,(short)(length));
  261.             break;
  262.         case 2:
  263.             for(offset=0;offset<length;++offset){
  264.             ensig=alaw(readbuf[offset]/8);
  265.             writebuf[offset]=ensig;
  266.             }
  267.             _write(ofh,writebuf,(short)(length));
  268.             break;
  269.         }
  270.         else
  271.         _write(ofh,readbuf,(short)length);
  272.     }
  273.     _close(ifh);
  274.     _close(ofh);
  275.     return(0);
  276. }
  277. /****************************************************************
  278. *     NAME : errorout()
  279. * DESCRIPTION : bad argument handler, prints usage header & exits
  280. *    INPUT : none
  281. *      OUTPUT : none
  282. *     RETURNS : does not return, exits to dos
  283. ****************************************************************/
  284. void errorout()
  285. {
  286.     printf("usage: fromwav filename [d] [a] [m]\n");
  287.     printf(" filename - input file = prefix[.suffix]\n");
  288.     printf("            output file = prefix.vox\n");
  289.     printf("            NO indexed play files\n");
  290.     printf(" d - default: adpcm encode\n");
  291.     printf(" a - alaw encode\n m - mulaw encode\n");
  292.     printf(" w - unwrap extended wave header\n");
  293.     _close(ifh);
  294.     _close(ofh);
  295.     exit(0);
  296. }
  297. /****************************************************************
  298. *     NAME : decode(encoded)
  299. * DESCRIPTION : does the actual adpcm decode
  300. *    INPUT : the encoded nibble from the adpcm file
  301. *      OUTPUT : the index into the step size table for the next encode
  302. *     RETURNS : the encoded difference
  303. ****************************************************************/
  304. int decode(unsigned char encoded)
  305. {
  306.     int diff,step;
  307.     step=stpsz[ssindex];
  308.     diff=nbl2bit[encoded][0]*(
  309.     step*nbl2bit[encoded][1]+
  310.     (step/2)*nbl2bit[encoded][2]+
  311.     (step/4)*nbl2bit[encoded][3]+
  312.     (step/8));
  313.     ssindex=ssindex+indsft[(encoded%8)];
  314.     if(ssindex<0)
  315.     ssindex=0;
  316.     if(ssindex>48)
  317.     ssindex=48;
  318.     return(diff);
  319. }
  320. unsigned char adpcm(int csig)
  321. {
  322.     int diff,step;
  323.     unsigned char encoded;
  324.     step=stpsz[ssindex];
  325.     if(csig>2047){
  326.     csig=2047;
  327.     printf("Input value exceeded +2047, value truncated\n");
  328.     }
  329.     if(csig<-2047){
  330.     csig=-2047;
  331.     printf("Input value exceeded -2047, value truncated\n");
  332.     }
  333.     diff=csig-signal;
  334.     if(diff<0){
  335.     encoded=8;
  336.     diff=-diff;
  337.     }
  338.     else
  339.     encoded=0;
  340.     if(diff>=step){
  341.     encoded+=4;
  342.     diff-=step;
  343.     }
  344.     step/=2;
  345.     if(diff>=step){
  346.     encoded+=2;
  347.     diff-=step;
  348.     }
  349.     step/=2;
  350.     if(diff>=step)
  351.     encoded+=1;
  352.     signal+=decode(encoded);
  353.     return(encoded);
  354. }
  355. unsigned char mulaw(int sig)
  356. {
  357.     int sign;
  358.     if(sig>0)
  359.     sign=255;
  360.     else{
  361.     sig=-sig;
  362.     sign=127;
  363.     }
  364.     if(sig<32)
  365.     return((unsigned char)(sign-sig/2));
  366.     if(sig<96)
  367.     return((unsigned char)(sign-sig/4-8));
  368.     if(sig<224)
  369.     return((unsigned char)(sign-sig/8-20));
  370.     if(sig<480)
  371.     return((unsigned char)(sign-sig/16-34));
  372.     if(sig<992)
  373.     return((unsigned char)(sign-sig/32-49));
  374.     if(sig<2016)
  375.     return((unsigned char)(sign-(sig+32)/64-64));
  376.     if(sig<4064)
  377.     return((unsigned char)(sign-(sig+32)/128-80));
  378.     if(sig<8160)
  379.     return((unsigned char)(sign-(sig+32)/256-96));
  380.     return((unsigned char)(sign-127));
  381. }
  382. unsigned char alaw(int sig)
  383. {
  384.     int sign;
  385.     if(sig<0){
  386.     sig=-sig;
  387.     sign=0;
  388.     }
  389.     else
  390.     sign=128;
  391.     if(sig<64)
  392.     return((unsigned char)((sign+sig/2)^0x55));
  393.     if(sig<128)
  394.     return((unsigned char)((sign+sig/4+16)^0x55));
  395.     if(sig<256)
  396.     return((unsigned char)((sign+sig/8+32)^0x55));
  397.     if(sig<512)
  398.     return((unsigned char)((sign+sig/16+48)^0x55));
  399.     if(sig<1024)
  400.     return((unsigned char)((sign+sig/32+64)^0x55));
  401.     if(sig<2048)
  402.     return((unsigned char)((sign+sig/64+80)^0x55));
  403.     if(sig<4096)
  404.     return((unsigned char)((sign+sig/128+96)^0x55));
  405.     return((unsigned char)((sign+127)^0x55));
  406. }
  407.