| 
2
 | 
     1 /*                                                           21.Mar.2000 V1.3
 | 
| 
 | 
     2   ============================================================================
 | 
| 
 | 
     3 
 | 
| 
 | 
     4   VBR-G726.C 
 | 
| 
 | 
     5   ~~~~~~~~~~
 | 
| 
 | 
     6 
 | 
| 
 | 
     7   Description: 
 | 
| 
 | 
     8   ~~~~~~~~~~~~
 | 
| 
 | 
     9   
 | 
| 
 | 
    10   Demonstration program for UGST/ITU-T G.726 module using the variable
 | 
| 
 | 
    11   bit rate feature. This version accepts either linear or G.711 A/u-law
 | 
| 
 | 
    12   input. Since this implementation of the G.726 requires G.711 compressed
 | 
| 
 | 
    13   samples, linear samples are converted to G.711 format before being
 | 
| 
 | 
    14   processed. Therefore, the same ammount of quantization distortion should
 | 
| 
 | 
    15   be expect either way.
 | 
| 
 | 
    16   
 | 
| 
 | 
    17   The modules called have been originally written in Fortran, and were
 | 
| 
 | 
    18   translated into C by the converter f2c, version of October 15, 1990
 | 
| 
 | 
    19   at 19:58:17.
 | 
| 
 | 
    20   
 | 
| 
 | 
    21   Input data is supposed to be aligned at word boundaries, i.e.,
 | 
| 
 | 
    22   organized in 16-bit words, following the operating system normal
 | 
| 
 | 
    23   organization (low-byte first for VMS and DOS; high byte first for most
 | 
| 
 | 
    24   Unix systems). Linear samples are supposed to be 16-bit right-adjusted. 
 | 
| 
 | 
    25   G711 compressed data is supposed to be in the 8 LEAST
 | 
| 
 | 
    26   significant bits of the word and the ADPCM data is in the LEAST 5
 | 
| 
 | 
    27   bits. Both are without sign extension.
 | 
| 
 | 
    28   
 | 
| 
 | 
    29   Output data will be generated in the same format as decribed above for
 | 
| 
 | 
    30   the input data.
 | 
| 
 | 
    31   
 | 
| 
 | 
    32   Usage:
 | 
| 
 | 
    33   ~~~~~~
 | 
| 
 | 
    34   $ VBR-G726 [-options] InpFile OutFile 
 | 
| 
 | 
    35              [FrameSize [1stBlock [NoOfBlocks [Reset]]]]
 | 
| 
 | 
    36   where:
 | 
| 
 | 
    37   InpFile     is the name of the file to be processed;
 | 
| 
 | 
    38   OutFile     is the name with the processed data;
 | 
| 
 | 
    39   FrameSize   is the frame size, in number of samples; the bitrate 
 | 
| 
 | 
    40               will only change in the boundaries of a frame 
 | 
| 
 | 
    41               [default: 16 samples]
 | 
| 
 | 
    42   1stBlock    is the number of the first block of the input file
 | 
| 
 | 
    43               to be processed [default: 1st block]
 | 
| 
 | 
    44   NoOfBlocks  is the number of blocks to be processed, starting on
 | 
| 
 | 
    45     	      block "1stBlock" [default: all blocks]
 | 
| 
 | 
    46 
 | 
| 
 | 
    47   Options:
 | 
| 
 | 
    48   -law #      the letters A or a for G.711 A-law, letter u for 
 | 
| 
 | 
    49               G.711 u-law, or letter l for linear. If linear is
 | 
| 
 | 
    50 	      chosen, A-law is used to compress/expand samples to/from
 | 
| 
 | 
    51 	      the G.726 routines. Default is A-law.
 | 
| 
 | 
    52   -rate #     is the bit-rate (in kbit/s): 40, 32, 24 or 16 (in kbit/s); 
 | 
| 
 | 
    53               or a combination of them using dashes (e.g. 32-24 or
 | 
| 
 | 
    54 	      16-24-32). Default is 32 kbit/s.
 | 
| 
 | 
    55   -frame #    Number of samples per frame for switching bit rates.
 | 
| 
 | 
    56               Default is 16 samples (or 2ms) 
 | 
| 
 | 
    57   -enc        run only the G.726 encoder on the samples 
 | 
| 
 | 
    58               [default: run encoder and decoder]
 | 
| 
 | 
    59   -dec        run only the G.726 decoder on the samples 
 | 
| 
 | 
    60               [default: run encoder and decoder]
 | 
| 
 | 
    61   -noreset    don't apply reset to the encoder/decoder
 | 
| 
 | 
    62   -?/-help    print help message
 | 
| 
 | 
    63 
 | 
| 
 | 
    64   Example:
 | 
| 
 | 
    65   $ vbr-G726 -law u -enc -rate 32 voice.ref voice.adp 256 3 45
 | 
| 
 | 
    66 
 | 
| 
 | 
    67   The command above takes the samples in file "voice.ref", already
 | 
| 
 | 
    68   in mu law format, processes the data through the G726 encoder
 | 
| 
 | 
    69   only at a rate of 32 bkit/s, saving them into the file
 | 
| 
 | 
    70   "voice.rel". The processing starts at block 3 for 45 blocks,
 | 
| 
 | 
    71   each block being 256 samples wide.
 | 
| 
 | 
    72 
 | 
| 
 | 
    73   Variables:
 | 
| 
 | 
    74   ~~~~~~~~~~
 | 
| 
 | 
    75   law  	  law to use (either A or u)
 | 
| 
 | 
    76   conv    desired processing
 | 
| 
 | 
    77   rate    desired rate
 | 
| 
 | 
    78   inpfil  input file name;
 | 
| 
 | 
    79   outfil  output file name;
 | 
| 
 | 
    80   N  	  block size;
 | 
| 
 | 
    81   N1  	  first block to process;
 | 
| 
 | 
    82   N2  	  no. of blocks to process;
 | 
| 
 | 
    83 
 | 
| 
 | 
    84   Exit values:
 | 
| 
 | 
    85   ~~~~~~~~~~~~
 | 
| 
 | 
    86   0  success (all but VMS);
 | 
| 
 | 
    87   1  success (only in VMS);
 | 
| 
 | 
    88   2  error opening input file;
 | 
| 
 | 
    89   3  error creating output file;
 | 
| 
 | 
    90   4  error moving pointer to desired start of conversion;
 | 
| 
 | 
    91   5  error reading input file;
 | 
| 
 | 
    92   6  error writing to file;
 | 
| 
 | 
    93   7  invalid law
 | 
| 
 | 
    94   8  invalid conversion
 | 
| 
 | 
    95   9  invalid rate
 | 
| 
 | 
    96 
 | 
| 
 | 
    97   Original author:
 | 
| 
 | 
    98   ~~~~~~~~~~~~~~~~
 | 
| 
 | 
    99   Simao Ferraz de Campos Neto
 | 
| 
 | 
   100   Comsat Laboratories                  Tel:    +1-301-428-4516
 | 
| 
 | 
   101   22300 Comsat Drive                   Fax:    +1-301-428-9287
 | 
| 
 | 
   102   Clarksburg MD 20871 - USA            E-mail: simao@ctd.comsat.com
 | 
| 
 | 
   103 
 | 
| 
 | 
   104   History:
 | 
| 
 | 
   105   ~~~~~~~~
 | 
| 
 | 
   106   10/Mar/1995 v1.0  Created based on vbr-g726.c
 | 
| 
 | 
   107   22/Feb/1996 v1.1  Removed compilation warnings, included headers as
 | 
| 
 | 
   108                     suggested by Kirchherr (FI/DBP Telekom) to run under
 | 
| 
 | 
   109 		    OpenVMS/AXP <simao@ctd.comsat.com>
 | 
| 
 | 
   110   22/Jul/1997 v1.2  Changed static allocation for data arrays to allow longer 
 | 
| 
 | 
   111                     frame sizes. Fix based on modifications by R. Kirchherr 
 | 
| 
 | 
   112                     <kirchherr@tzd.telekom.de>
 | 
| 
 | 
   113   21.Mar.2000 v1.3  Corrected bug when the bitrate is not specified by 
 | 
| 
 | 
   114                     the user. Corrected bug that made incorrect
 | 
| 
 | 
   115                     calculation on total number of blocks to process
 | 
| 
 | 
   116                     when the block size is not a multiple of the file
 | 
| 
 | 
   117                     size. <simao.campos@labs.comsat.com>
 | 
| 
 | 
   118   ============================================================================
 | 
| 
 | 
   119 */
 | 
| 
 | 
   120 
 | 
| 
 | 
   121 /* ..... General definitions for UGST demo programs ..... */
 | 
| 
 | 
   122 #include "ugstdemo.h"
 | 
| 
 | 
   123 
 | 
| 
 | 
   124 /* ..... General include ..... */
 | 
| 
 | 
   125 #include <stdio.h>
 | 
| 
 | 
   126 #include <stdlib.h>
 | 
| 
 | 
   127 #include <string.h>
 | 
| 
 | 
   128 #include <math.h>
 | 
| 
 | 
   129 #include <ctype.h>
 | 
| 
 | 
   130 
 | 
| 
 | 
   131 #if defined(VMS)
 | 
| 
 | 
   132 #include <unixio.h>
 | 
| 
 | 
   133 #include <stat.h>
 | 
| 
 | 
   134 #else                           /* Unix/DOS */
 | 
| 
 | 
   135 #include <sys/stat.h>
 | 
| 
 | 
   136 #endif
 | 
| 
 | 
   137 
 | 
| 
 | 
   138 /* ..... G.726 module as include functions ..... */
 | 
| 
 | 
   139 #include "g726.h"
 | 
| 
 | 
   140 #include "g711.h"
 | 
| 
 | 
   141 
 | 
| 
 | 
   142 /*
 | 
| 
 | 
   143  -------------------------------------------------------------------------
 | 
| 
 | 
   144  void parse_rate(char *str, short *rate);
 | 
| 
 | 
   145  ~~~~~~~~~~~~~~~
 | 
| 
 | 
   146  Parses string str with a list of bitrates for the operation of the G726
 | 
| 
 | 
   147  algorithm and return a list of them in rate, and the number of rates read.
 | 
| 
 | 
   148 
 | 
| 
 | 
   149  Parameters:
 | 
| 
 | 
   150  ~~~~~~~~~~~
 | 
| 
 | 
   151  str ..... string pointing to a list of dash-separated bitrates to be used.
 | 
| 
 | 
   152            Valid examples are: 16 (single rate), 32-24 (duo-rate), etc.
 | 
| 
 | 
   153  rate .... string of short numbers with each of the specified rates.
 | 
| 
 | 
   154 
 | 
| 
 | 
   155  Return:
 | 
| 
 | 
   156  ~~~~~~~
 | 
| 
 | 
   157  Returns the number of bitrates for the ADPCM operation, 0 if str is 
 | 
| 
 | 
   158  empty or improper, and -1 if there are too many rates requested.
 | 
| 
 | 
   159 
 | 
| 
 | 
   160  History:
 | 
| 
 | 
   161  ~~~~~~~~
 | 
| 
 | 
   162  10.Mar.95 v1.0 Created <simao@ctd.comsat.com>
 | 
| 
 | 
   163  -------------------------------------------------------------------------
 | 
| 
 | 
   164 */
 | 
| 
 | 
   165 int parse_rate(str, rate)
 | 
| 
 | 
   166 char *str;
 | 
| 
 | 
   167 short **rate;
 | 
| 
 | 
   168 {
 | 
| 
 | 
   169   char *s = str;
 | 
| 
 | 
   170   int count = 1, i;
 | 
| 
 | 
   171 
 | 
| 
 | 
   172   if (str == NULL)
 | 
| 
 | 
   173     return 0;
 | 
| 
 | 
   174 
 | 
| 
 | 
   175   while ((s = strchr(s, '-')) != NULL) {
 | 
| 
 | 
   176     s++;
 | 
| 
 | 
   177     count++;
 | 
| 
 | 
   178   }
 | 
| 
 | 
   179 
 | 
| 
 | 
   180   /* Allocates memory for the necessary number of rates */
 | 
| 
 | 
   181   *rate = (short *) calloc(sizeof(short), count);
 | 
| 
 | 
   182   if (*rate == NULL)
 | 
| 
 | 
   183     return (-1);
 | 
| 
 | 
   184 
 | 
| 
 | 
   185   /* Save rates in the array */
 | 
| 
 | 
   186   for (s = strtok(str, "-"), i = 0; i < count; i++) {
 | 
| 
 | 
   187     /* Convert to short & save */
 | 
| 
 | 
   188     (*rate)[i] = atoi(s);
 | 
| 
 | 
   189 
 | 
| 
 | 
   190     /* Classification of rate - return 0 if invalid rate was specified */
 | 
| 
 | 
   191     if ((*rate)[i] > 5) {
 | 
| 
 | 
   192       if ((*rate)[i] == 40)
 | 
| 
 | 
   193         (*rate)[i] = 5;
 | 
| 
 | 
   194       else if ((*rate)[i] == 32)
 | 
| 
 | 
   195         (*rate)[i] = 4;
 | 
| 
 | 
   196       else if ((*rate)[i] == 24)
 | 
| 
 | 
   197         (*rate)[i] = 3;
 | 
| 
 | 
   198       else if ((*rate)[i] == 16)
 | 
| 
 | 
   199         (*rate)[i] = 2;
 | 
| 
 | 
   200       else
 | 
| 
 | 
   201         return (0);
 | 
| 
 | 
   202     }
 | 
| 
 | 
   203 
 | 
| 
 | 
   204     /* Update s to the next valid rate number */
 | 
| 
 | 
   205     s = strtok(NULL, "-");
 | 
| 
 | 
   206   }
 | 
| 
 | 
   207 
 | 
| 
 | 
   208   /* Return the number of rates */
 | 
| 
 | 
   209   return (count);
 | 
| 
 | 
   210 }
 | 
| 
 | 
   211 
 | 
| 
 | 
   212 /* .................... End of parse_rate() ........................... */
 | 
| 
 | 
   213 
 | 
| 
 | 
   214 
 | 
| 
 | 
   215 /*
 | 
| 
 | 
   216  -------------------------------------------------------------------------
 | 
| 
 | 
   217  void display_usage(void);
 | 
| 
 | 
   218  ~~~~~~~~~~~~~~~~~~
 | 
| 
 | 
   219  Display proper usage for the demo program. Generated automatically from
 | 
| 
 | 
   220  program documentation.
 | 
| 
 | 
   221 
 | 
| 
 | 
   222  History:
 | 
| 
 | 
   223  ~~~~~~~~
 | 
| 
 | 
   224  10.Mar.95 v1.0 Created <simao>.
 | 
| 
 | 
   225  -------------------------------------------------------------------------
 | 
| 
 | 
   226 */
 | 
| 
 | 
   227 #define P(x) printf x
 | 
| 
 | 
   228 void display_usage()
 | 
| 
 | 
   229 {
 | 
| 
 | 
   230   P(("Version 1.3 of 21/Mar/2000 \n\n"));
 | 
| 
 | 
   231 
 | 
| 
 | 
   232   P(("  VBR-G726.C \n"));
 | 
| 
 | 
   233   P(("  Demonstration program for UGST/ITU-T G.726 module using the variable\n"));
 | 
| 
 | 
   234   P(("  bit rate feature. This version accepts either linear or G.711 A/u-law\n"));
 | 
| 
 | 
   235   P(("  input. Since this implementation of the G.726 requires G.711 compressed\n"));
 | 
| 
 | 
   236   P(("  samples, linear samples are converted to G.711 format before being\n"));
 | 
| 
 | 
   237   P(("  processed. Therefore, the same ammount of quantization distortion should\n"));
 | 
| 
 | 
   238   P(("  be expect either way.\n"));
 | 
| 
 | 
   239   P(("  Input data is supposed to be aligned at word boundaries, i.e.,\n"));
 | 
| 
 | 
   240   P(("  organized in 16-bit words, following the operating system normal\n"));
 | 
| 
 | 
   241   P(("  organization (low-byte first for VMS and DOS; high byte first for most\n"));
 | 
| 
 | 
   242   P(("  Unix systems). Linear samples are supposed to be 16-bit right-adjusted. \n"));
 | 
| 
 | 
   243   P(("  G711 compressed data is supposed to be in the 8 LEAST\n"));
 | 
| 
 | 
   244   P(("  significant bits of the word and the ADPCM data is in the LEAST 5\n"));
 | 
| 
 | 
   245   P(("  bits. Both are without sign extension.\n"));
 | 
| 
 | 
   246   P(("  \n"));
 | 
| 
 | 
   247   P(("  Output data will be generated in the same format as decribed above for\n"));
 | 
| 
 | 
   248   P(("  the input data.\n"));
 | 
| 
 | 
   249   P(("  \n"));
 | 
| 
 | 
   250   P(("  Usage:\n"));
 | 
| 
 | 
   251   P(("  VBR-G726 [-options] InpFile OutFile \n"));
 | 
| 
 | 
   252   P(("             [FrameSize [1stBlock [NoOfBlocks [Reset]]]]\n"));
 | 
| 
 | 
   253   P(("  where:\n"));
 | 
| 
 | 
   254   P(("  InpFile     is the name of the file to be processed;\n"));
 | 
| 
 | 
   255   P(("  OutFile     is the name with the processed data;\n"));
 | 
| 
 | 
   256   P(("  FrameSize   is the frame size, in number of samples; the bitrate \n"));
 | 
| 
 | 
   257   P(("              will only change in the boundaries of a frame \n"));
 | 
| 
 | 
   258   P(("              [default: 16 samples]\n"));
 | 
| 
 | 
   259   P(("  1stBlock    is the number of the first block of the input file\n"));
 | 
| 
 | 
   260   P(("              to be processed [default: 1st block]\n"));
 | 
| 
 | 
   261   P(("  NoOfBlocks  is the number of blocks to be processed, starting on\n"));
 | 
| 
 | 
   262   P(("              block \"1stBlock\" [default: all blocks]\n"));
 | 
| 
 | 
   263   P(("\n"));
 | 
| 
 | 
   264   P(("  Options:\n"));
 | 
| 
 | 
   265   P(("  -law #      the letters A or a for G.711 A-law, letter u for \n"));
 | 
| 
 | 
   266   P(("              G.711 u-law, or letter l for linear. If linear is\n"));
 | 
| 
 | 
   267   P(("              chosen, A-law is used to compress/expand samples to/from\n"));
 | 
| 
 | 
   268   P(("              the G.726 routines. Default is A-law.\n"));
 | 
| 
 | 
   269   P(("  -rate #     is the bit-rate (in kbit/s): 40, 32, 24 or 16 (in kbit/s); \n"));
 | 
| 
 | 
   270   P(("              or a combination of them using dashes (e.g. 32-24 or\n"));
 | 
| 
 | 
   271   P(("              16-24-32). Default is 32 kbit/s.\n"));
 | 
| 
 | 
   272   P(("  -frame #    Number of samples per frame for switching bit rates.\n"));
 | 
| 
 | 
   273   P(("              Default is 16 samples (or 2ms) \n"));
 | 
| 
 | 
   274   P(("  -enc        run only the G.726 encoder on the samples \n"));
 | 
| 
 | 
   275   P(("              [default: run encoder and decoder]\n"));
 | 
| 
 | 
   276   P(("  -dec        run only the G.726 decoder on the samples \n"));
 | 
| 
 | 
   277   P(("              [default: run encoder and decoder]\n"));
 | 
| 
 | 
   278   P(("  -noreset    don't apply reset to the encoder/decoder\n"));
 | 
| 
 | 
   279   P(("  -?/-help    print help message\n"));
 | 
| 
 | 
   280   P(("\n"));
 | 
| 
 | 
   281 
 | 
| 
 | 
   282   /* Quit program */
 | 
| 
 | 
   283   exit(-128);
 | 
| 
 | 
   284 }
 | 
| 
 | 
   285 
 | 
| 
 | 
   286 #undef P
 | 
| 
 | 
   287 /* .................... End of display_usage() ........................... */
 | 
| 
 | 
   288 
 | 
| 
 | 
   289 
 | 
| 
 | 
   290 void G726_initEncode(G726_state *encoder_state)
 | 
| 
 | 
   291 {
 | 
| 
 | 
   292   memset(encoder_state, 0, sizeof(G726_state));
 | 
| 
 | 
   293 }
 | 
| 
 | 
   294 
 | 
| 
 | 
   295 void G726_initDecode(G726_state *decoder_state)
 | 
| 
 | 
   296 {
 | 
| 
 | 
   297   memset(decoder_state, 0, sizeof(G726_state));
 | 
| 
 | 
   298 }
 | 
| 
 | 
   299 
 | 
| 
 | 
   300 void g726pack(Byte *packed, short *in, int cnt)
 | 
| 
 | 
   301 {
 | 
| 
 | 
   302   int i;
 | 
| 
 | 
   303   for (i = 0; i <= cnt; i += 2, ++packed, ++in) {
 | 
| 
 | 
   304     *packed = (*in & 0xF);
 | 
| 
 | 
   305     ++in;
 | 
| 
 | 
   306     *packed += (*in & 0xF) * 16;
 | 
| 
 | 
   307   }
 | 
| 
 | 
   308 }
 | 
| 
 | 
   309 
 | 
| 
 | 
   310 void g726unpack(short *out, Byte *packed, int cnt)
 | 
| 
 | 
   311 {
 | 
| 
 | 
   312   int i;
 | 
| 
 | 
   313   for (i = 0; i <= cnt; i += 2, ++packed, ++out) {
 | 
| 
 | 
   314     *out = (*packed & 0xF);
 | 
| 
 | 
   315     ++out;
 | 
| 
 | 
   316     *out = (*packed & 0xF0) / 16;
 | 
| 
 | 
   317   }
 | 
| 
 | 
   318 }
 | 
| 
 | 
   319 
 | 
| 
 | 
   320 /*
 | 
| 
 | 
   321    **************************************************************************
 | 
| 
 | 
   322    ***                                                                    ***
 | 
| 
 | 
   323    ***        Demo-Program for testing the correct implementation         ***
 | 
| 
 | 
   324    ***               and to show how to use the programs                  ***
 | 
| 
 | 
   325    ***                                                                    ***
 | 
| 
 | 
   326    **************************************************************************
 | 
| 
 | 
   327 */
 | 
| 
 | 
   328 int main(argc, argv)
 | 
| 
 | 
   329 int argc;
 | 
| 
 | 
   330 char *argv[];
 | 
| 
 | 
   331 {
 | 
| 
 | 
   332   G726_state encoder_state, decoder_state;
 | 
| 
 | 
   333   long N = 16, N1 = 1, N2 = 0, cur_blk, smpno;
 | 
| 
 | 
   334   short *tmp_buf, *inp_buf, *out_buf, reset = 1;
 | 
| 
 | 
   335   Byte tmpb_buf[N], outb_buf[N];
 | 
| 
 | 
   336   short inp_type, out_type, *rate = 0;
 | 
| 
 | 
   337   char encode = 1, decode = 1, law[4] = "A", def_rate[] = "32";
 | 
| 
 | 
   338   int rateno = 1, rate_idx;
 | 
| 
 | 
   339 
 | 
| 
 | 
   340   /* General-purpose, progress indication */
 | 
| 
 | 
   341   static char quiet = 0, funny[9] = "|/-\\|/-\\";
 | 
| 
 | 
   342 
 | 
| 
 | 
   343 /* File variables */
 | 
| 
 | 
   344   char FileIn[80], FileOut[80];
 | 
| 
 | 
   345   FILE *Fi, *Fo;
 | 
| 
 | 
   346   int inp, out;
 | 
| 
 | 
   347   long start_byte;
 | 
| 
 | 
   348 #ifdef VMS
 | 
| 
 | 
   349   char mrs[15];
 | 
| 
 | 
   350 #endif
 | 
| 
 | 
   351 
 | 
| 
 | 
   352 /*
 | 
| 
 | 
   353  * ......... PARAMETERS FOR PROCESSING .........
 | 
| 
 | 
   354  */
 | 
| 
 | 
   355 
 | 
| 
 | 
   356   /* GETTING OPTIONS */
 | 
| 
 | 
   357 
 | 
| 
 | 
   358   if (argc < 2)
 | 
| 
 | 
   359     display_usage();
 | 
| 
 | 
   360   else {
 | 
| 
 | 
   361     while (argc > 1 && argv[1][0] == '-')
 | 
| 
 | 
   362       if (strcmp(argv[1], "-noreset") == 0) {
 | 
| 
 | 
   363         /* No reset */
 | 
| 
 | 
   364         reset = 0;
 | 
| 
 | 
   365 
 | 
| 
 | 
   366         /* Update argc/argv to next valid option/argument */
 | 
| 
 | 
   367         argv++;
 | 
| 
 | 
   368         argc--;
 | 
| 
 | 
   369       } else if (strcmp(argv[1], "-enc") == 0) {
 | 
| 
 | 
   370         /* Encoder-only operation */
 | 
| 
 | 
   371         encode = 1;
 | 
| 
 | 
   372         decode = 0;
 | 
| 
 | 
   373 
 | 
| 
 | 
   374         /* Move argv over the option to the next argument */
 | 
| 
 | 
   375         argv++;
 | 
| 
 | 
   376         argc--;
 | 
| 
 | 
   377       } else if (strcmp(argv[1], "-dec") == 0) {
 | 
| 
 | 
   378         /*Decoder-only operation */
 | 
| 
 | 
   379         encode = 0;
 | 
| 
 | 
   380         decode = 1;
 | 
| 
 | 
   381 
 | 
| 
 | 
   382         /* Move argv over the option to the next argument */
 | 
| 
 | 
   383         argv++;
 | 
| 
 | 
   384         argc--;
 | 
| 
 | 
   385       } else if (strcmp(argv[1], "-law") == 0) {
 | 
| 
 | 
   386         /* Define law for operation: A, u, or linear */
 | 
| 
 | 
   387         switch (toupper(argv[2][0])) {
 | 
| 
 | 
   388         case 'A':
 | 
| 
 | 
   389           law[0] = '1';
 | 
| 
 | 
   390           break;
 | 
| 
 | 
   391         case 'U':
 | 
| 
 | 
   392           law[0] = '0';
 | 
| 
 | 
   393           break;
 | 
| 
 | 
   394         case 'L':
 | 
| 
 | 
   395           law[0] = '2';
 | 
| 
 | 
   396           break;
 | 
| 
 | 
   397         default:
 | 
| 
 | 
   398           HARAKIRI(" Invalid law (A or u)! Aborted...\n", 7);
 | 
| 
 | 
   399         }
 | 
| 
 | 
   400 
 | 
| 
 | 
   401         /* Move argv over the option to the next argument */
 | 
| 
 | 
   402         argv += 2;
 | 
| 
 | 
   403         argc -= 2;
 | 
| 
 | 
   404       } else if (strcmp(argv[1], "-frame") == 0) {
 | 
| 
 | 
   405         /* Define Frame size for rate change during operation */
 | 
| 
 | 
   406         N = atoi(argv[2]);
 | 
| 
 | 
   407 
 | 
| 
 | 
   408         /* Move argv over the option to the next argument */
 | 
| 
 | 
   409         argv += 2;
 | 
| 
 | 
   410         argc -= 2;
 | 
| 
 | 
   411       } else if (strcmp(argv[1], "-rate") == 0) {
 | 
| 
 | 
   412         /*Define rate(s) for operation */
 | 
| 
 | 
   413         rateno = parse_rate(argv[2], &rate);
 | 
| 
 | 
   414         if (rateno == 0) {
 | 
| 
 | 
   415           fprintf(stderr, "Invalid bitrate list: %s\n", argv[2]);
 | 
| 
 | 
   416           exit(9);
 | 
| 
 | 
   417         }
 | 
| 
 | 
   418         /* Move argv over the option to the next argument */
 | 
| 
 | 
   419         argv += 2;
 | 
| 
 | 
   420         argc -= 2;
 | 
| 
 | 
   421       } else if (strcmp(argv[1], "-q") == 0) {
 | 
| 
 | 
   422         /* Don't print progress indicator */
 | 
| 
 | 
   423         quiet = 1;
 | 
| 
 | 
   424 
 | 
| 
 | 
   425         /* Move argv over the option to the next argument */
 | 
| 
 | 
   426         argv++;
 | 
| 
 | 
   427         argc--;
 | 
| 
 | 
   428       } else if (strcmp(argv[1], "-?") == 0
 | 
| 
 | 
   429         || strcmp(argv[1], "-help") == 0) {
 | 
| 
 | 
   430         /* Print help */
 | 
| 
 | 
   431         display_usage();
 | 
| 
 | 
   432       } else {
 | 
| 
 | 
   433         fprintf(stderr,
 | 
| 
 | 
   434           "ERROR! Invalid option \"%s\" in command line\n\n", argv[1]);
 | 
| 
 | 
   435         display_usage();
 | 
| 
 | 
   436       }
 | 
| 
 | 
   437   }
 | 
| 
 | 
   438 
 | 
| 
 | 
   439   /* Now get regular parameters */
 | 
| 
 | 
   440   GET_PAR_S(1, "_Input File: .................. ", FileIn);
 | 
| 
 | 
   441   GET_PAR_S(2, "_Output File: ................. ", FileOut);
 | 
| 
 | 
   442   FIND_PAR_L(3, "_Block Size: .................. ", N, N);
 | 
| 
 | 
   443   FIND_PAR_L(4, "_Starting Block: .............. ", N1, N1);
 | 
| 
 | 
   444   FIND_PAR_L(5, "_No. of Blocks: ............... ", N2, N2);
 | 
| 
 | 
   445 
 | 
| 
 | 
   446   /* Uses default rate if none is given */
 | 
| 
 | 
   447   if (rate == 0)
 | 
| 
 | 
   448     rateno = parse_rate(def_rate, &rate);
 | 
| 
 | 
   449 
 | 
| 
 | 
   450   /* Inform user of the compading law used: 0->u, 1->A, 2->linear */
 | 
| 
 | 
   451   fprintf(stderr, "Using %s\n",
 | 
| 
 | 
   452     law[0] == '1' ? "A-law" : (law[0] == '0' ? "u-law" : "linear PCM"));
 | 
| 
 | 
   453 
 | 
| 
 | 
   454   /* Find starting byte in file */
 | 
| 
 | 
   455   start_byte = sizeof(short) * (long) (--N1) * (long) N;
 | 
| 
 | 
   456 
 | 
| 
 | 
   457   /* Check if is to process the whole file */
 | 
| 
 | 
   458   if (N2 == 0) {
 | 
| 
 | 
   459     struct stat st;
 | 
| 
 | 
   460 
 | 
| 
 | 
   461     /* ... find the input file size ... */
 | 
| 
 | 
   462     stat(FileIn, &st);
 | 
| 
 | 
   463     N2 = ceil((st.st_size - start_byte) / (double) (N * sizeof(short)));
 | 
| 
 | 
   464   }
 | 
| 
 | 
   465 
 | 
| 
 | 
   466   /* Define correct data I/O types */
 | 
| 
 | 
   467   if (encode && decode) {
 | 
| 
 | 
   468     inp_type = out_type = (law[0] == '2' ? IS_LIN : IS_LOG);
 | 
| 
 | 
   469   } else if (encode) {
 | 
| 
 | 
   470     inp_type = law[0] == '2' ? IS_LIN : IS_LOG;
 | 
| 
 | 
   471     out_type = IS_ADPCM;
 | 
| 
 | 
   472   } else {
 | 
| 
 | 
   473     inp_type = IS_ADPCM;
 | 
| 
 | 
   474     out_type = law[0] == '2' ? IS_LIN : IS_LOG;
 | 
| 
 | 
   475   }
 | 
| 
 | 
   476 
 | 
| 
 | 
   477   /* Force law to be used *by the ADPCM* to A-law, if input is linear */
 | 
| 
 | 
   478   if (law[0] == '2')
 | 
| 
 | 
   479     law[0] = '1';
 | 
| 
 | 
   480 
 | 
| 
 | 
   481 /*
 | 
| 
 | 
   482  * ...... MEMORY ALLOCATION .........
 | 
| 
 | 
   483  */
 | 
| 
 | 
   484 
 | 
| 
 | 
   485   if ((inp_buf = (short *) calloc(N, sizeof(short))) == NULL)
 | 
| 
 | 
   486     HARAKIRI("Error in memory allocation!\n", 1);
 | 
| 
 | 
   487   if ((out_buf = (short *) calloc(N, sizeof(short))) == NULL)
 | 
| 
 | 
   488     HARAKIRI("Error in memory allocation!\n", 1);
 | 
| 
 | 
   489   if ((tmp_buf = (short *) calloc(N, sizeof(short))) == NULL)
 | 
| 
 | 
   490     HARAKIRI("Error in memory allocation!\n", 1);
 | 
| 
 | 
   491 
 | 
| 
 | 
   492 /*
 | 
| 
 | 
   493  * ......... FILE PREPARATION .........
 | 
| 
 | 
   494  */
 | 
| 
 | 
   495 
 | 
| 
 | 
   496   /* Opening input file; abort if there's any problem */
 | 
| 
 | 
   497   if ((Fi = fopen(FileIn, "rb")) == NULL)
 | 
| 
 | 
   498     KILL(FileIn, 2);
 | 
| 
 | 
   499   inp = fileno(Fi);
 | 
| 
 | 
   500 
 | 
| 
 | 
   501   /* Creates output file */
 | 
| 
 | 
   502 #ifdef VMS
 | 
| 
 | 
   503   sprintf(mrs, "mrs=%d", 512);
 | 
| 
 | 
   504 #endif
 | 
| 
 | 
   505   if ((Fo = fopen(FileOut, WB)) == NULL)
 | 
| 
 | 
   506     KILL(FileOut, 3);
 | 
| 
 | 
   507   out = fileno(Fo);
 | 
| 
 | 
   508 
 | 
| 
 | 
   509   /* Move pointer to 1st block of interest */
 | 
| 
 | 
   510   if (fseek(Fi, start_byte, 0) < 0l)
 | 
| 
 | 
   511     KILL(FileIn, 4);
 | 
| 
 | 
   512 
 | 
| 
 | 
   513 /*
 | 
| 
 | 
   514  * ......... PROCESSING ACCORDING TO ITU-T G.726 .........
 | 
| 
 | 
   515  */
 | 
| 
 | 
   516   /* Reset VBR counters */
 | 
| 
 | 
   517   rate_idx = 0;
 | 
| 
 | 
   518 
 | 
| 
 | 
   519   for (cur_blk = 0; cur_blk < N2; cur_blk++) {
 | 
| 
 | 
   520     /* Set the proper rate index */
 | 
| 
 | 
   521     rate_idx = cur_blk % rateno;
 | 
| 
 | 
   522 
 | 
| 
 | 
   523     /* Print progress flag */
 | 
| 
 | 
   524     if (!quiet)
 | 
| 
 | 
   525 #ifdef DISPLAY_CURRENT_RATE
 | 
| 
 | 
   526       fprintf(stderr, "%d-", 8 * rate[rate_idx]);
 | 
| 
 | 
   527 #else
 | 
| 
 | 
   528       fprintf(stderr, "%c\r", funny[cur_blk % 8]);
 | 
| 
 | 
   529 #endif
 | 
| 
 | 
   530 
 | 
| 
 | 
   531     /* Read a block of samples */
 | 
| 
 | 
   532     if ((smpno = fread(inp_buf, sizeof(short), N, Fi)) < 0)
 | 
| 
 | 
   533       KILL(FileIn, 5);
 | 
| 
 | 
   534 
 | 
| 
 | 
   535     /* Compress linear input samples */
 | 
| 
 | 
   536     if (inp_type == IS_LIN) {
 | 
| 
 | 
   537       /* Compress using A-law */
 | 
| 
 | 
   538       alaw_compress(smpno, inp_buf, tmpb_buf);
 | 
| 
 | 
   539 
 | 
| 
 | 
   540       /* copy temporary buffer over input buffer */
 | 
| 
 | 
   541       // memcpy(inp_buf, tmp_buf, sizeof(short) * smpno);
 | 
| 
 | 
   542     }
 | 
| 
 | 
   543 
 | 
| 
 | 
   544     /* Check if reset is needed */
 | 
| 
 | 
   545     reset = (reset == 1 && cur_blk == 0) ? 1 : 0;
 | 
| 
 | 
   546 
 | 
| 
 | 
   547     /* Carry out the desired operation */
 | 
| 
 | 
   548     if (encode && !decode)
 | 
| 
 | 
   549       G726_encode(tmpb_buf, out_buf, smpno, law,
 | 
| 
 | 
   550         rate[rate_idx], reset, &encoder_state);
 | 
| 
 | 
   551     else if (decode && !encode)
 | 
| 
 | 
   552       G726_decode(inp_buf, outb_buf, smpno, law,
 | 
| 
 | 
   553         rate[rate_idx], reset, &decoder_state);
 | 
| 
 | 
   554     else if (encode && decode) {
 | 
| 
 | 
   555       Byte g726_buf[N/2];
 | 
| 
 | 
   556     
 | 
| 
 | 
   557       G726_encode(tmpb_buf, tmp_buf, smpno, law,
 | 
| 
 | 
   558         rate[rate_idx], reset, &encoder_state);
 | 
| 
 | 
   559         // printf ("rate[rate_idx] = %d\n", rate[rate_idx]);
 | 
| 
 | 
   560       g726pack(g726_buf, tmp_buf, smpno);
 | 
| 
 | 
   561       
 | 
| 
 | 
   562       g726unpack(tmp_buf, g726_buf, smpno);
 | 
| 
 | 
   563         
 | 
| 
 | 
   564       G726_decode(tmp_buf, outb_buf, smpno, law,
 | 
| 
 | 
   565         rate[rate_idx], reset, &decoder_state);
 | 
| 
 | 
   566     }
 | 
| 
 | 
   567 
 | 
| 
 | 
   568     /* Expand linear input samples */
 | 
| 
 | 
   569     if (out_type == IS_LIN) {
 | 
| 
 | 
   570       /* Compress using A-law */
 | 
| 
 | 
   571       alaw_expand(smpno, outb_buf, tmp_buf);
 | 
| 
 | 
   572 
 | 
| 
 | 
   573       /* copy temporary buffer over input buffer */
 | 
| 
 | 
   574       memcpy(out_buf, tmp_buf, sizeof(short) * smpno);
 | 
| 
 | 
   575     }
 | 
| 
 | 
   576 
 | 
| 
 | 
   577     /* Write ADPCM output word */
 | 
| 
 | 
   578     if ((smpno = fwrite(out_buf, sizeof(short), smpno, Fo)) < 0)
 | 
| 
 | 
   579       KILL(FileOut, 6);
 | 
| 
 | 
   580   }
 | 
| 
 | 
   581 
 | 
| 
 | 
   582 /*
 | 
| 
 | 
   583  * ......... FINALIZATIONS .........
 | 
| 
 | 
   584  */
 | 
| 
 | 
   585 
 | 
| 
 | 
   586   /* Free allocated memory */
 | 
| 
 | 
   587   free(tmp_buf);
 | 
| 
 | 
   588   free(out_buf);
 | 
| 
 | 
   589   free(inp_buf);
 | 
| 
 | 
   590   free(rate);
 | 
| 
 | 
   591 
 | 
| 
 | 
   592   /* Close input and output files */
 | 
| 
 | 
   593   fclose(Fi);
 | 
| 
 | 
   594   fclose(Fo);
 | 
| 
 | 
   595 
 | 
| 
 | 
   596   /* Exit with success for non-vms systems */
 | 
| 
 | 
   597 #ifndef VMS
 | 
| 
 | 
   598   return (0);
 | 
| 
 | 
   599 #endif
 | 
| 
 | 
   600 }
 | 
| 
 | 
   601 
 | 
| 
 | 
   602 /* ............................. end of main() ............................. */
 |