home *** CD-ROM | disk | FTP | other *** search
/ Current Shareware 1994 January / SHAR194.ISO / modem / zfax.zip / VCNVT.C < prev    next >
Text File  |  1993-03-15  |  12KB  |  320 lines

  1.  
  2. /**************************************************************************
  3.                         VCNVT.C
  4.  
  5.  Note : This file is for the voice file conversion between the ZyXEL 2, 3-bits
  6.         ADPCM format and the Sound Blaster .VOC file format. (9.6k sampling
  7.         uncompressed waveform)
  8.  
  9.  Usage : vcnvt  0  sfile dfile
  10.                 ^    ^     ^
  11.                 |    |     +--- Destination file path and name
  12.                 |    |
  13.                 |    +--- Source file path and name
  14.                 |
  15.                 +----- 0 : convert from .ZyXEL ADPCM to .VOC format
  16.                 +----- 1 : convert from .VOC to ZyXEL 2 bits ADPCM format
  17.                 +----- 2 : convert from .VOC to ZyXEL 3 bits ADPCM format
  18.  
  19.  Created by Lin Chinru, Jan. 5, 1993.  R&D Dep., ZyXEL Comm. Corp.
  20.  Copyright 1993, ZyXEL Communications Corporation
  21.  Updated by Javier Achirica.
  22.  **************************************************************************/
  23. #include <string.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #ifdef __GNUC__
  27. #include <unistd.h>
  28. #endif
  29.  
  30. void ToVoc(int) ;
  31. void ToAdpcm(int) ;
  32. void Quit(int,char *) ;
  33. void Adaptive(char) ;
  34.  
  35.  
  36. char    Rcnt, CompBit ;
  37. FILE    *SourFh, *DestFh ;
  38.  
  39. int     Rdata, EstMax, Delta, Data, Pack, RepCount ;
  40. long    BlkCnt, RepPos ;
  41. int     MaxTbl[] = { 0x399A, 0x3A9F, 0x4D14, 0x6607 } ;
  42.  
  43. /* ------------------------------------------------- */
  44. /* Reserved buffers for the ZyXEL ADPCM file header  */
  45. /* ------------------------------------------------- */
  46. char    ZheadBuf0[16] ;
  47. char    ZheadBuf1[16] = { 'Z','y','X','E','L',2,0,0,0,0,0,0,0,0,0,0 } ;
  48.  
  49. /* ------------------------------------------ */
  50. /* Reserved buffers for the .VOC file header  */
  51. /* ------------------------------------------ */
  52. char    VheadBuf0[32] ;
  53. char    VheadBuf1[32] = { 'C','r','e','a','t','i','v','e',' ',\
  54.                           'V','o','i','c','e',' ','F','i','l','e',\
  55.                           0x1a,0x1a,0,0x0a,1,0x29,0x11,\
  56.                           1, 2, 0, 0, 0x98, 0 } ;
  57.  
  58. void main(int argc, char *argv[])
  59. {
  60.         /* ---------- Open file and check for legality -------------- */
  61.         if ( argc!=4 || (*argv[1] < '0' || *argv[1] > '2') )
  62.                 Quit(0,"") ;
  63.         if ( (SourFh=fopen(argv[2],"rb")) == NULL )
  64.                 Quit(1,argv[2]) ;
  65.         if ( (DestFh=fopen(argv[3],"wb")) == NULL )
  66.                 Quit(1,argv[3]) ;
  67.  
  68.         /* ------------------ */
  69.         /* Initial parameters */
  70.         /* ------------------ */
  71.         Rdata   = 0 ;
  72.         Rcnt    = 8 ;
  73.         Delta   = 5 ;
  74.         EstMax  = 0 ;
  75.         BlkCnt  = 2 ;
  76.  
  77.         /* -------------------------------- */
  78.         /*  ZyXEL ADPCM -> .VOC conversion  */
  79.         /* -------------------------------- */
  80.         if ( *argv[1]=='0' )       {
  81.                 fread( ZheadBuf0, sizeof(char), 16, SourFh) ;
  82.                 if ( memcmp( ZheadBuf0, ZheadBuf1, 6) || ZheadBuf0[10]==0 )
  83.                         Quit(2,argv[2]) ;
  84.                 fwrite( VheadBuf1, sizeof(char), 32, DestFh) ;
  85.                 CompBit = ZheadBuf0[10] ;
  86.                 if ( CompBit == 1 ) {
  87.                         MaxTbl[0] = 0x3800 ;
  88.                         MaxTbl[1] = 0x5600 ;
  89.                 }
  90.                 while ( (Data=getc(SourFh)) != EOF )    {
  91.                         if ( CompBit == 1 )     {
  92.                                 ToVoc((Data&0xc0)>>6) ; /* XX-- ---- */
  93.                                 ToVoc((Data&0x30)>>4) ; /* --XX ---- */
  94.                                 ToVoc((Data&0x0c)>>2) ; /* ---- XX-- */
  95.                                 ToVoc(Data&0x03) ;      /* ---- --XX */
  96.                         }
  97.                         else    {
  98.                                 ToVoc((Data&0xe0)>>5) ; /* XXX- ---- */
  99.                                 ToVoc((Data&0x1c)>>2) ; /* ---X XX-- */
  100.                                 Pack = (Data&0x03)<<1 ;
  101.                                 Data = getc(SourFh) ;
  102.                                 ToVoc(Pack|((Data&0x80)>>7)) ;
  103.                                 ToVoc((Data&0x70)>>4) ; /* -XXX ---- */
  104.                                 ToVoc((Data&0x0e)>>1) ; /* ---- XXX- */
  105.                                 Pack = (Data&0x01)<<2 ;
  106.                                 Data = getc(SourFh) ;
  107.                                 ToVoc(Pack|((Data&0xc0)>>6)) ;
  108.                                 ToVoc((Data&0x38)>>3) ; /* --XX X--- */
  109.                                 ToVoc(Data&0x07) ;      /* ---- -XXX */
  110.                         }
  111.                 }
  112.                 putc( 0, DestFh) ;
  113.                 fseek( DestFh, 27, SEEK_SET ) ;
  114.                 fwrite( &BlkCnt, 1, 3, DestFh ) ;
  115.         }
  116.  
  117.         /* -------------------------------- */
  118.         /*  .VOC -> ZyXEL ADPCM conversion  */
  119.         /* -------------------------------- */
  120.         else    {
  121.                 fread( VheadBuf0, sizeof(char), 26, SourFh) ;
  122.                 if ( memcmp( VheadBuf0, VheadBuf1, 22) )
  123.                         Quit(2,argv[2]) ;
  124.                 CompBit = *argv[1]-'0' ;
  125.                 if ( CompBit == 1 ) {
  126.                         MaxTbl[0] = 0x3800 ;
  127.                         MaxTbl[1] = 0x5600 ;
  128.                 }
  129.                 ZheadBuf1[10] = CompBit ;
  130.                 fwrite( ZheadBuf1, sizeof(char), 16, DestFh) ;
  131.  
  132.                 /* Pack = 0->terminator, 1->read sampling rate
  133.                           2->read data, 3->silence, 6->repeat count,
  134.                           7->end repeat, others->bypass */
  135.                 while ( ((Pack=getc(SourFh))!=0) && (Pack!=EOF)) {
  136.                         /* Read the block length */
  137.                 fread( &BlkCnt, 1, 3, SourFh ) ;
  138.                         /* Read the sampling rate, 9600 is required */
  139.                 switch ( Pack )
  140.                     {
  141.                     case 1:
  142.                        /* Data should be 8 bit at aprox. 9600 Hz */
  143.                         fread( &Data, 1, 2, SourFh ) ;
  144.                         if ( Data<147 || Data>157 )
  145.                                 Quit(2,argv[2]) ;
  146.                         BlkCnt -= 2 ;
  147.                     case 2:
  148.                         for ( ; BlkCnt; --BlkCnt )
  149.                                 ToAdpcm( getc(SourFh) ) ;
  150.                         break;
  151.                     case 3:
  152.                         fread( &BlkCnt, 1, 2, SourFh ) ;
  153.                         BlkCnt *= 104 ;
  154.                         BlkCnt /= 256 - getc(SourFh) ;
  155.                         for ( ; BlkCnt; --BlkCnt )
  156.                                 ToAdpcm( 127 ) ;
  157.                         break;
  158.                     case 6:
  159.                         fread( &RepCount, 1, 2, SourFh ) ;
  160.                         BlkCnt -= 2;
  161.                         RepPos = BlkCnt + ftell( SourFh ) ;
  162.                         break;
  163.                     case 7:
  164.                         if ( RepCount )
  165.                         {
  166.                             --RepCount ;
  167.                             if ( RepPos ) fseek( SourFh, RepPos - BlkCnt, SEEK_SET ) ;
  168.                         }
  169.                     }
  170.                     fseek( SourFh, BlkCnt, SEEK_CUR ) ;
  171.                 }
  172.         }
  173.         fclose(SourFh) ;
  174.         fclose(DestFh) ;
  175. }
  176.  
  177.  
  178. /**************************************************************************
  179.         ToVoc()
  180.  
  181.  
  182.  
  183.  Copyright 1992, ZyXEL Communications Corporation
  184.  ************************************************************************/
  185. void ToVoc(int Vdata)
  186. {
  187. int     Wdata ;
  188.  
  189.         Adaptive((char)Vdata) ;
  190.         if ( EstMax > 8191 )
  191.                 Wdata = 8191 ;
  192.         else if ( EstMax < -8192 )
  193.                 Wdata = -8192 ;
  194.         else
  195.                 Wdata = EstMax ;
  196.         putc( ((Wdata>>6)+128)&0xff, DestFh ) ;
  197.         ++BlkCnt ;
  198. }
  199.  
  200. /**************************************************************************
  201.         ToAdpcm()
  202.  
  203.  
  204.  
  205.  Copyright 1992, ZyXEL Communications Corporation
  206.  ************************************************************************/
  207. void ToAdpcm(int Edata)
  208. {
  209. char    TmpCompBit, DataBit ;
  210.  
  211.  
  212.         DataBit = 0 ;
  213.         Rdata  &= 0xff00 ;
  214.  
  215.         Edata -= 128 ;
  216.         Edata <<= 6 ;
  217.         Edata += 32 ;
  218.         /* Check for the waveform data and quantize this data */
  219.         if ( Edata -= EstMax )  {
  220.                 TmpCompBit = 2*CompBit ;
  221.                 /* ----------------------------------------------------- */
  222.                 /* If the data is negative, set flag and change the sign */
  223.                 /* ----------------------------------------------------- */
  224.                 if ( Edata < 0 ) {
  225.                         Edata = -Edata ;
  226.                         DataBit = TmpCompBit ;
  227.                 }
  228.                 /* --------------------------------------------------- */
  229.                 /* Quantize the waveform data, delta value is adaptive */
  230.                 /* --------------------------------------------------- */
  231.                 while ( ((Edata-=Delta)>0) && --TmpCompBit!=0 )
  232.                         DataBit += 1 ;
  233.                 /* ---------------------------- */
  234.                 /* Rdata is the compressed data */
  235.                 /* ---------------------------- */
  236.                 Rdata |= ( DataBit << (7-CompBit) ) ;
  237.         }
  238.         /* ------------------------------------------------------ */
  239.         /* check if the compressed data can be pack into one byte */
  240.         /* ------------------------------------------------------ */
  241.         TmpCompBit = CompBit+1 ;
  242.         while ( TmpCompBit-- )     {
  243.                 Rdata <<= 1 ;
  244.                 if ( !(--Rcnt) )    {
  245.                         putc(Rdata>>8,DestFh) ;
  246.                         Rcnt = 8 ;
  247.                 }
  248.         }
  249.         /* -------------------------------------- */
  250.         /* Adaptive the Delta and Estimat Maximum */
  251.         /* -------------------------------------- */
  252.         Adaptive(DataBit) ;
  253. }
  254.  
  255.  
  256. /**************************************************************************
  257.         Adaptive(DataBit, SignBit)
  258.  
  259.  
  260.  
  261.  Copyright 1992, ZyXEL Communications Corporation
  262.  ************************************************************************/
  263. void Adaptive(char DataBit)
  264. {
  265. int     TmpMax ;
  266. char    SignBit ;
  267. long    TmpDelta ;
  268.  
  269.         SignBit = DataBit & (2*CompBit) ;
  270.         DataBit &= ~(2*CompBit) ;
  271.         if ( (Delta&1) && !SignBit )
  272.                 ++EstMax ;
  273.  
  274.         /* ------------------- */
  275.         /* Calculate the Delta */
  276.         /* ------------------- */
  277.         TmpDelta = Delta ;
  278.         TmpDelta *= MaxTbl[DataBit] ;
  279.         TmpDelta += 8192 ;
  280.         TmpDelta >>= 14 ;
  281.  
  282.         /* -------------------- */
  283.         /* Calculate the EstMax */
  284.         /* -------------------- */
  285.         TmpMax  = (Delta>>1) ;
  286.         while ( DataBit-- )
  287.                 TmpMax += Delta ;
  288.         if ( SignBit )
  289.                 EstMax -= TmpMax ;
  290.         else
  291.                 EstMax += TmpMax ;
  292.         Delta = (int)TmpDelta ;
  293. }
  294.  
  295. /**************************************************************************
  296.         Quit()
  297.  
  298.  
  299.  
  300.  Copyright 1992, ZyXEL Communications Corporation
  301.  ************************************************************************/
  302. void Quit(int Num, char *MsgStr)
  303. {
  304.         if ( Num == 0 ) {
  305.                 printf("Usage : vcnvt 0 sfile dfile.\n");
  306.                 printf("              ^   ^     ^\n") ;
  307.                 printf("              │   │     └ Destination file\n");
  308.                 printf("              │   └────── Source file\n") ;
  309.                 printf("              └────────── Convert type : \n") ;
  310.                 printf("    0 : convert from .ZyXEL ADPCM to .VOC format.\n") ;
  311.                 printf("    1 : convert from .VOC to ZyXEL 2 bits ADPCM.\n") ;
  312.                 printf("    2 : convert from .VOC to ZyXEL 3 bits ADPCM.\n") ;
  313.         }
  314.         else if ( Num == 1 )
  315.                 printf("Can't open %s\n", MsgStr) ;
  316.         else if ( Num == 2 )
  317.                 printf("File format error on %s\n", MsgStr) ;
  318.         exit(1) ;
  319. }
  320.