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

  1. /****************************************************************
  2. *     NAME : towav
  3. * DESCRIPTION : converts encoded pcm file to linear pcm
  4. *          : and prepends a riff file header to make it
  5. *          : playable as a .wav file
  6. *    INPUT : options:  filename [d] [a] [m] [6] [8] [w]
  7. *          : filename input file name preffix[.suffix]
  8. *          : d adpcm decode - default
  9. *          : a alaw decode
  10. *          : m mulaw decode
  11. *          : 6 6khz sampling - default
  12. *          : 8 8khz sampling
  13. *          : w wrap with extended wave header
  14. *      OUTPUT : file "preffix.wav"
  15. *     RETURNS : none
  16. *     NOTE : written with microsoft c7.0, thus the extra _'s
  17. *          : on the compiler defines, use the oldnames library
  18. *          : to avoid the same problem with the functions
  19. ****************************************************************/
  20.  
  21. /* standard headers */
  22. #include <string.h>
  23. #include <ctype.h>
  24. #include <conio.h>
  25. #include <stdlib.h>
  26. #include <process.h>
  27. #include <stdio.h>
  28. #include <fcntl.h>
  29. #include <io.h>
  30. #include <sys/types.h>
  31. #include <sys/stat.h>
  32. /* standard wave file header */
  33. /****************************************************************
  34. * 'RIFF'
  35. * length in bytes of all that follows(long)
  36. * 'WAVE'
  37. * 'fmt '
  38. * length in bytes of the format block = 16(long)
  39. * format = 1(int)
  40. * number of channels = 1(int) - mono
  41. * sample rate(long)
  42. * bytes per second during play(long)
  43. * bytes per sample = 2(int)
  44. * bits per sample = 16(int)
  45. * 'data'
  46. * length in bytes of the data block(long)
  47. ****************************************************************/
  48. long wavehdr[11]=
  49. {0x46464952,0xffffffdb,0x45564157,0x20746d66,16,0x10001,6000,12000,0x100002,
  50. 0x61746164,-1};
  51. /*extended wave file header */
  52. /****************************************************************
  53. * 'RIFF'
  54. * length in bytes of all that follows(long)
  55. * 'WAVE'
  56. * 'fmt '
  57. * length in bytes of the format block = 18+extra bytes(long)
  58. * format = ?(int)
  59. * number of channels = 1(int) - mono
  60. * sample rate(long)
  61. * bytes per second during play(long)
  62. * bytes per sample = ?(int)
  63. * bits per sample = ?(int)
  64. * number of extra bytes = ?(int)
  65. * extra bytes
  66. * 'data'
  67. * length in bytes of the data block(long)
  68. ****************************************************************/
  69. long adpcmhdr[12]=
  70. {0x46464952,0xffffffdb,0x45564157,0x20746d66,20,0x10010,6000,3000,0x40001,
  71. 0x2,0x61746164,-1};
  72. long pcmhdr[12]=
  73. {0x46464952,0xffffffdb,0x45564157,0x20746d66,18,0x10007,6000,6000,0x80001,
  74. 0x6174,0x6164ffff,-1};
  75. /* alaw decode table */
  76. int alaw[256]=
  77. {-688,-656,-752,-720,-560,-528,-624,-592,-944,-912,-1008,-976,
  78. -816,-784,-880,-848,-344,-328,-376,-360,-280,-264,-312,-296,
  79. -472,-456,-504,-488,-408,-392,-440,-424,-2752,-2624,-3008,-2880,
  80. -2240,-2112,-2496,-2368,-3776,-3648,-4032,-3904,-3264,-3136,
  81. -3520,-3392,-1376,-1312,-1504,-1440,-1120,-1056,-1248,-1184,
  82. -1888,-1824,-2016,-1952,-1632,-1568,-1760,-1696,-43,-41,-47,-45,
  83. -35,-33,-39,-37,-59,-57,-63,-61,-51,-49,-55,-53,-11,-9,-15,
  84. -13,-3,-1,-7,-5,-27,-25,-31,-29,-19,-17,-23,-21,-172,-164,
  85. -188,-180,-140,-132,-156,-148,-236,-228,-252,-244,-204,-196,
  86. -220,-212,-86,-82,-94,-90,-70,-66,-78,-74,-118,-114,-126,-122,
  87. -102,-98,-110,-106,688,656,752,720,560,528,624,592,944,912,
  88. 1008,976,816,784,880,848,344,328,376,360,280,264,312,296,472,
  89. 456,504,488,408,392,440,424,2752,2624,3008,2880,2240,2112,
  90. 2496,2368,3776,3648,4032,3904,3264,3136,3520,3392,1376,1312,
  91. 1504,1440,1120,1056,1248,1184,1888,1824,2016,1952,1632,1568,
  92. 1760,1696,43,41,47,45,35,33,39,37,59,57,63,61,51,49,55,53,
  93. 11,9,15,13,3,1,7,5,27,25,31,29,19,17,23,21,172,164,188,
  94. 180,140,132,156,148,236,228,252,244,204,196,220,212,86,82,
  95. 94,90,70,66,78,74,118,114,126,122,102,98,110,106};
  96. /* mulaw decode table */
  97. int mulaw[256]=
  98. {-8031,-7775,-7519,-7263,-7007,-6751,-6495,-6239,-5983,-5727,-5471,
  99. -5215,-4959,-4703,-4447,-4191,-3999,-3871,-3743,-3615,-3487,
  100. -3359,-3231,-3103,-2975,-2847,-2719,-2591,-2463,-2335,-2207,
  101. -2079,-1983,-1919,-1855,-1791,-1727,-1663,-1599,-1535,-1471,
  102. -1407,-1343,-1279,-1215,-1151,-1087,-1023,-975,-943,-911,-879,
  103. -847,-815,-783,-751,-719,-687,-655,-623,-591,-559,-527,-495,
  104. -471,-455,-439,-423,-407,-391,-375,-359,-343,-327,-311,-295,
  105. -279,-263,-247,-231,-219,-211,-203,-195,-187,-179,-171,-163,
  106. -155,-147,-139,-131,-123,-115,-107,-99,-93,-89,-85,-81,-77,
  107. -73,-69,-65,-61,-57,-53,-49,-45,-41,-37,-33,-30,-28,-26,-24,
  108. -22,-20,-18,-16,-14,-12,-10,-8,-6,-4,-2,0,8031,7775,7519,
  109. 7263,7007,6751,6495,6239,5983,5727,5471,5215,4959,4703,4447,
  110. 4191,3999,3871,3743,3615,3487,3359,3231,3103,2975,2847,2719,
  111. 2591,2463,2335,2207,2079,1983,1919,1855,1791,1727,1663,1599,
  112. 1535,1471,1407,1343,1279,1215,1151,1087,1023,975,943,911,879,
  113. 847,815,783,751,719,687,655,623,591,559,527,495,471,455,439,
  114. 423,407,391,375,359,343,327,311,295,279,263,247,231,219,211,
  115. 203,195,187,179,171,163,155,147,139,131,123,115,107,99,93,
  116. 89,85,81,77,73,69,65,61,57,53,49,45,41,37,33,30,28,26,24,
  117. 22,20,18,16,14,12,10,8,6,4,2,0};
  118. /* step size index shift table */
  119. int indsft[8]={-1, -1, -1, -1, 2, 4, 6, 8};
  120. /* step size table
  121.     stpsz[i]=floor[16*(11/10)^i] */
  122. int stpsz[49]=
  123. {16,17,19,21,23,25,28,31,34,37,41,45,50,55,60,66,73,80,88,
  124. 97,107,118,130,143,157,173,190,209,230,253,279,307,337,371,
  125. 408,449,494,544,598,658,724,796,876,963,1060,1166,1282,1411,
  126. 1552};
  127. /* nibble to bit map */
  128. int nbl2bit[16][4]={
  129. {1,0,0,0},{1,0,0,1},{1,0,1,0},{1,0,1,1},{1,1,0,0},{1,1,0,1},
  130. {1,1,1,0},{1,1,1,1},{-1,0,0,0},{-1,0,0,1},{-1,0,1,0},{-1,0,1,1},
  131. {-1,1,0,0},{-1,1,0,1},{-1,1,1,0},{-1,1,1,1}};
  132. /* step size index */
  133. int ssindex=0;
  134. /* the current adpcm signal */
  135. int signal=-2;
  136. /* tmp storage for last 128 values */
  137. int avgbuf[128]={
  138. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  139. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  140. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  141. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  142. };
  143. /* index for same */
  144. int avgidx=0;
  145. /* total length decoded */
  146. long total=0;
  147. /* length of the current read buffer */
  148. long length;
  149. /* offset into the current read buffer */
  150. long offset;
  151. /* nibble of the byte */
  152. int nibble;
  153. /* read buffer */
  154. unsigned char readbuf[4096];
  155. /* write buffer */
  156. unsigned int writebuf[8192];
  157. /* decode method: 0 -> adpcm, 1 -> mulaw, 2 -> alaw */
  158. int law=0;
  159. /* wrap only flag */
  160. int wrap=0;
  161. /* input & output file handles */
  162. int ifh,ofh;
  163. void truncwarn();
  164. void errorout();
  165. int decode(unsigned char);
  166. /****************************************************************
  167. *        NAME : main(argc,argv)
  168. * DESCRIPTION : entrypoint to application
  169. *    INPUT : options:  filename [d] [a] [m] [6] [8] [w]
  170. *          : filename input file name preffix[.suffix]
  171. *          : d adpcm decode - default
  172. *          : a alaw decode
  173. *          : m mulaw decode
  174. *          : 6 6khz sampling - default
  175. *          : 8 8khz sampling
  176. *          : w wrap with extended wave header
  177. *      OUTPUT : none
  178. *     RETURNS : none
  179. ****************************************************************/
  180. int main (int argc,char *argv[])
  181. {
  182. int argn;        /* argument index */
  183. int slth,sidx;        /* string hacking variables */
  184. char oname[12];
  185. int yeanea;
  186.     /* wellllll, we really do need input data */
  187.     if(argc<2){
  188.     printf("\nNo input file\n\n");
  189.     errorout();
  190.     }
  191.     /* honest we do */
  192.     if((ifh=_open(argv[1],_O_RDONLY|_O_BINARY))<0){
  193.     printf("\nInput file %s was not opened\n\n",argv[1]);
  194.     errorout();
  195.     }
  196.     /* check the rest of the arguments*/
  197.     if(argc>2){
  198.     for(argn=2;argn<argc;++argn){
  199.         switch(tolower(*argv[argn])){
  200.         case 'd':        /* adpcm decode */
  201.             law=0;
  202.             break;
  203.         case 'm':
  204.             law=1;        /* mulaw decode */
  205.             pcmhdr[5]=0x10006;
  206.             break;
  207.         case 'a':
  208.             law=2;        /* alaw decode */
  209.             pcmhdr[5]=0x10007;
  210.             break;
  211.         case '8':
  212.             wavehdr[6]=8000;    /* 8khz sampling */
  213.             wavehdr[7]=16000;
  214.             adpcmhdr[6]=8000;
  215.             adpcmhdr[7]=4000;
  216.             pcmhdr[6]=8000;
  217.             pcmhdr[7]=8000;
  218.             break;
  219.         case '6':
  220.             wavehdr[6]=6000;    /* 6khz sampling */
  221.             wavehdr[7]=12000;
  222.             adpcmhdr[6]=6000;
  223.             adpcmhdr[7]=3000;
  224.             pcmhdr[6]=6000;
  225.             pcmhdr[7]=6000;
  226.             break;
  227.         case 'w':
  228.             wrap=1;
  229.         default:
  230.             printf("\nUnknown Option - %c\n\n",*argv[argn]);
  231.             errorout();
  232.         }
  233.     }
  234.     }
  235.     /* build the output file name */
  236.     strcpy(oname,argv[1]);
  237.     slth=strlen(oname);
  238.     /* get the prefix */
  239.     for(sidx=0;sidx<slth;++sidx)
  240.     if(oname[sidx]=='.')
  241.         break;
  242.     oname[sidx]=0;        /* convert to asciz */
  243.     strcat(oname,".wav");   /* tack on our suffix */
  244.     /* opps, maybe */
  245.     if((ofh=_open(oname,_O_RDONLY))>0){
  246.     printf("output file %s already exits\n",oname);
  247.     printf("Ok to replace (y or n)? ");
  248.     yeanea=_getch();
  249.     printf("%c\n",yeanea);
  250.     if(yeanea=='y'||yeanea=='Y')
  251.         _close(ofh);
  252.     else
  253.         errorout();
  254.     }
  255.     /* this should never happen */
  256.     if((ofh=_open(oname,_O_WRONLY|_O_BINARY|_O_CREAT|_O_TRUNC,_S_IWRITE))<0){
  257.     printf("output file %s not opened\n",oname);
  258.     errorout();
  259.     }
  260.     if(wrap==0)
  261.     _write(ofh,wavehdr,44);
  262.     else
  263.     if(law==0)
  264.         _write(ofh,adpcmhdr,48);
  265.     else
  266.         _write(ofh,pcmhdr,46);
  267.     length=4096;
  268.     while(length==4096){
  269.     length=_read(ifh,readbuf,4096);
  270.     if(wrap==0)
  271.         switch(law){
  272.         case 0:
  273.             for(offset=0;offset<length;++offset){
  274.             nibble=0;
  275.             signal+=decode((unsigned char)(readbuf[offset]/16));
  276.             if(signal>2047||signal<-2047)
  277.                 truncwarn();
  278.             writebuf[2*offset]=signal*16;
  279.             nibble=1;
  280.             signal+=decode((unsigned char)(readbuf[offset]%16));
  281.             if(signal>2047||signal<-2047)
  282.                 truncwarn();
  283.             writebuf[2*offset+1]=signal*16;
  284.             }
  285.             _write(ofh,writebuf,(unsigned)(4*length));
  286.             break;
  287.         case 1:
  288.             for(offset=0;offset<length;++offset)
  289.             writebuf[offset]=mulaw[readbuf[offset]]*4;
  290.             _write(ofh,writebuf,(unsigned)(2*length));
  291.             break;
  292.         case 2:
  293.             for(offset=0;offset<length;++offset)
  294.             writebuf[offset]=alaw[readbuf[offset]]*8;
  295.             _write(ofh,writebuf,(unsigned)(2*length));
  296.             break;
  297.         }
  298.     else
  299.         _write(ofh,readbuf,(unsigned)length);
  300.     total+=length;
  301.     }
  302.     _close(ifh);
  303.     /* go back and fill in the wave length */
  304.     length=_lseek(ofh,(long)4,SEEK_SET);
  305.     if(wrap==0){
  306.     if(law==0)
  307.         total=4*total;
  308.     else
  309.         total=2*total;
  310.     length=total+36;
  311.     }
  312.     else
  313.     if(law==0)
  314.         length=total+40;
  315.     else
  316.         length=total+38;
  317.     _write(ofh,&length,4);
  318.     /* go back and fill in the data length */
  319.     if(wrap==0)
  320.     length=_lseek(ofh,(long)40,SEEK_SET);
  321.     else
  322.     if(law==0)
  323.         length=_lseek(ofh,(long)44,SEEK_SET);
  324.     else
  325.         length=_lseek(ofh,(long)42,SEEK_SET);
  326.     _write(ofh,&total,4);
  327.     _close(ofh);
  328.     return(0);
  329. }
  330. /****************************************************************
  331. *     NAME : truncwarn()
  332. * DESCRIPTION : prints a message when the decode goes out of bounds
  333. *    INPUT : none
  334. *      OUTPUT : none
  335. *     RETURNS : none
  336. ****************************************************************/
  337. void truncwarn()
  338. {
  339.     long value;
  340.     value=2*total+2*offset+nibble;
  341.     printf("adpcm decode truncated to 12bit value at nibble %ld\n",
  342.     value);
  343.     if(signal>2047)
  344.     signal=2047;
  345.     if(signal<-2047)
  346.     signal=-2047;
  347. }
  348. /****************************************************************
  349. *     NAME : errorout()
  350. * DESCRIPTION : bad argument handler, prints usage header & exits
  351. *    INPUT : none
  352. *      OUTPUT : none
  353. *     RETURNS : does not return, exits to dos
  354. ****************************************************************/
  355. void errorout()
  356. {
  357.     printf("usage: towav filename [d] [a] [m] [6] [8] [w]\n");
  358.     printf(" filename - input file = prefix[.suffix]\n");
  359.     printf("            output file = prefix.wav\n");
  360.     printf("            NO indexed play files\n");
  361.     printf(" d - default: adpcm decode\n");
  362.     printf(" a - alaw decode\n m - mulaw decode\n");
  363.     printf(" 6 - default: 6000 samples/second\n 8 - 8000 samples/second\n");
  364.     printf(" w - wrap in extended wave header(no decode)\n");
  365.     _close(ifh);
  366.     _close(ofh);
  367.     exit(0);
  368. }
  369. /****************************************************************
  370. *     NAME : decode(encoded)
  371. * DESCRIPTION : does the actual adpcm decode
  372. *    INPUT : the encoded nibble from the adpcm file
  373. *      OUTPUT : the index into the step size table for the next decode
  374. *     RETURNS : the decoded difference
  375. ****************************************************************/
  376. int decode(unsigned char encoded)
  377. {
  378.     int diff,step;
  379.     step=stpsz[ssindex];
  380.     diff=nbl2bit[encoded][0]*(
  381.     step*nbl2bit[encoded][1]+
  382.     (step/2)*nbl2bit[encoded][2]+
  383.     (step/4)*nbl2bit[encoded][3]+
  384.     (step/8));
  385.     ssindex=ssindex+indsft[(encoded%8)];
  386.     if(ssindex<0)
  387.     ssindex=0;
  388.     if(ssindex>48)
  389.     ssindex=48;
  390.     return(diff);
  391. }
  392.