diff intercom/g711/g711demo.c @ 2:13be24d74cd2

import intercom-0.4.1
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 09:57:52 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/intercom/g711/g711demo.c	Fri Jun 25 09:57:52 2010 +0200
@@ -0,0 +1,459 @@
+/*                                                        11.Apr.2000 v3.2
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+  G711DEMO.C
+
+  Description:
+  ~~~~~~~~~~~~
+  Example-program for converting from linear samples to A/u law log
+  compression and vice-versa, according to ITU-T Rec.G711.
+
+  Usage:
+  ~~~~~~
+  $ g711demo [-?] [-r] [-skip skip] Law Transf InpFile OutFile
+             [BlockSize [1stBlock [NoOfBlocks]]]
+
+  where:
+  Law	      is the law desired (either A or u)
+  Transf      is the desired convertion on the input file:
+              [lili], linear to linear: lin -> (A/u)log -> lin
+              [lilo], linear to (A/u)-log
+              [loli], (A/u) log to linear
+  InpFile     is the name of the file to be processed;
+  OutFile     is the name with the compressed/expanded data;
+  BlockSize   is the block size, in number of samples (16 -bit words)
+              (default is 256);
+  1stBlock    is the number of the first block of the input file
+              to be processed. (Default: 1)
+  NoOfBlocks  is the number of blocks to be processed, starting on
+              block "1stBlock". (default is til end-of-file)
+
+  Options:
+  -?            display usage and quit.
+  -r            disables even-bit swap by A-law encoding and decoding.
+                By default, even bits of the A-law samples ARE inverted
+                by alaw_compress() at return time, as well as by
+                alaw_expand() at its beginning. With the option
+                "-r", the log samples have NOT their even bits
+                inverted before being saved to disk NOR after
+                read from a file.
+  -skip         is the number of samples to skip before the beginning
+                of the 1st block.
+
+  Example:
+  $ G711 u lili voice.ref voice.rel 256 3 45
+
+  The command above takes the samples in file "voice.ref" and converts
+  them to A-law and back to linear, saving them into file "voice.rel",
+  starting at block 3 for 45 blocks, each block being 256 samples wide.
+
+  Variables:
+  ~~~~~~~~~~
+  law              law to use (either A or u)
+  conv              desired processing
+  inpfil              input file name;
+  outfil              output file name;
+  N              block size;
+  N1              first block to filter;
+  N2              no. of blocks to filter;
+
+  Compilation of Demo Program:
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+  The test program allows to process binary/ILS files of any size by
+  loading segments of data from/to file. The size of the working
+  segment must be entered.
+
+  VAX/VMS:
+  $ CC G711
+  $ link G711
+  $ G711 :== $G711_Disk:[G711_Dir]G711
+  $ G711 u lili ifile ofile 233 3 47
+
+  This command line invokes the u-law utility, converts from linear
+  over ulaw to linear. It processes the input file "ifile" by
+  loading segments of 233 samples and writes the result to "ofile",
+  from the 3rd segment, for 47 segments.
+  
+  Turbo-C, Turbo-C++:
+  > tcc G711
+  > G711 a lilo ifile ofile 39 1
+
+  This command line invokes the a-law utility, converts from linear
+  to a-law.  It processes the input file "ifile" by loading
+  segments of 39 samples and writes the result (alaw-samples) to
+  "ofile", starting from the beginning of the file. It will ask
+  the number of segments.
+
+  HighC (MetaWare, version R2.32):
+  > hc386 G711.c
+  > Run386 G711 a loli ifile ofile 3333
+
+  This command line invokes the a-law utility, converts from a-law
+  to linear It processes the input file "ifile" (alaw-samples) by
+  loading segments of 3333 samples and writes the result (linear
+  samples) to "ofile". It will ask the starting segment and the
+  number of segments.
+
+  SunC (SunOS - BSD Unix)
+  # cc -o g711demo g711demo.c
+  # g711demo a lilo ifile ofile 256 1 132
+
+  Exit values:
+  ~~~~~~~~~~~~
+   0   success (all but VMS);
+   1   success (only in VMS);
+   2   error opening input file;
+   3   error creating output file;
+   4   error moving pointer to desired start of conversion;
+   5   error reading input file;
+   6   error writing to file;
+   7   invalid law
+   8   invalid conversion
+  10   error allocating memory
+
+  Prototypes:
+  ~~~~~~~~~~~
+  Needs ugstdemo.h and includes g711.h.
+
+  Authors:
+  ~~~~~~~~
+  Simao Ferraz de Campos Neto         Rudolf Hofmann
+  CPqD/Telebras                       PHILIPS KOMMUNIKATIONS INDUSTRIE AG
+  DDS/Pr.11                           Kommunikationssysteme
+  Rd. Mogi Mirim-Campinas Km.118      Thurn-und-Taxis-Strasse 14
+  13.080-061 - Campinas - SP (Brazil) D-8500 Nuernberg 10 (Germany)
+
+  Phone : +55-192-39-6637             Phone : +49-911-526-2603
+  FAX   : +55-192-39-2179             FAX   : +49-911-526-3385
+  EMail : tdsimao@cpqd.ansp.br        EMail : hf@pkinbg.uucp
+
+  History:
+  ~~~~~~~~
+  07.Feb.1991 v1.0 Release of 1st demo program for G711 module (CPqD).
+  10.Dec.1991 v2.0 Demo program incorporated in G711 module and
+                   rebuild by PKI.
+  08.Feb.1992 v2.1 Demo separated from module file; ILS header
+                   manipulation removed; low level I/O; changes to
+                   assure compatibility with Unix (SunOS).
+  14.Apr.1993 v3.0 Inclusion of display_usage() and of option "-r"
+                   <tdsimao@venus.cpqd.ansp.br>
+  22.Feb.1996 v3.1 Removed compilation warnings, included headers as
+                   suggested by Kirchherr (FI/DBP Telekom) to run under
+                   OpenVMS/AXP <simao@ctd.comsat.com>
+  11.Apr.2000 v3.2 Corrected bug that made incorrect calculation on
+                   total number of blocks to process when the block
+                   size is not a multiple of the file
+                   size. <simao.campos@labs.comsat.com>
+  13jan2005        Byte for compressed data
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+#include "ugstdemo.h"           /* UGST defines for demo programs */
+
+/* Include general headers */
+#include <stdio.h>              /* UNIX Standard I/O Definitions */
+#include <ctype.h>              /* Character Type Classification */
+#include <string.h>             /* String handling functions */
+#include <stdlib.h>             /* General utility definitions */
+#include <math.h>
+
+/* Include OS dependent headers */
+#if defined(VMS)
+#include <stat.h>
+#else                           /* Others */
+#include <sys/stat.h>
+#endif
+
+
+/* G711 module functions */
+#include "g711.h"
+
+
+/*
+  --------------------------------------------------------------------------
+   void display_usage()
+
+   Displays usage of the program. Upon completion, aborts the program.
+
+   Created by <tdsimao@cpqd.ansp.br>, 14.Apr.93
+
+  --------------------------------------------------------------------------
+*/
+#define FP(x) fprintf(stderr, x)
+void display_usage()
+{
+  FP("\n  G711DEMO.C   --- Version v3.2 of 11.Apr.2000 \n");
+  FP("\n");
+  FP("  Description:\n");
+  FP("  ~~~~~~~~~~~~\n");
+  FP("  Example-program for converting from linear samples to A/u law log\n");
+  FP("  compression and vice-versa, according to ITU-T Rec.G711.\n");
+  FP("\n");
+  FP("  Usage:\n");
+  FP("  ~~~~~~\n");
+  FP("  $ G711 [-r] Law Transf InpFile OutFile BlkSize 1stBlock NoOfBlocks\n");
+  FP("\n");
+  FP("  where:\n");
+  FP("  Law	   is the law desired (either A or u)\n");
+  FP("  Transf	   is the desired convertion on the input file:\n");
+  FP("	             [lili], linear to linear: lin -> (A/u)log -> lin\n");
+  FP("               [lilo], linear to (A/u)-log\n");
+  FP("               [loli], (A/u) log to linear\n");
+  FP("  InpFile	   is the name of the file to be processed;\n");
+  FP("  OutFile	   is the name with the compressed/expanded data;\n");
+  FP("  BlkSize    is number of samples per block [256];\n");
+  FP("  1stBlock   is the number of the first block of the input file\n");
+  FP("		   to be processed [1].\n");
+  FP("  NoOfBlocks is the number of blocks to be processed, starting on\n");
+  FP("		   block `1stBlock'. Default is til end-of-file.\n");
+  FP("\n");
+  FP("  Options:\n");
+  FP("  -?         displays this message.\n");
+  FP("  -r         disables even-bit swap by A-law encoding and decoding.\n");
+  FP("  -skip      is the number of samples to skip.\n");
+  FP("\n");
+
+  /* Quit program */
+  exit(1);
+}
+
+#undef FP
+/* ..................... End of display_usage() .......................... */
+
+
+/*
+   **************************************************************************
+   ***                                                                    ***
+   ***        Demo-Program for testing the correct implementation         ***
+   ***               and to show how to use the programs                  ***
+   ***                                                                    ***
+   **************************************************************************
+*/
+int main(argc, argv)
+int argc;
+char *argv[];
+{
+  long i, N, N1, N2, smpno, tot_smpno, cur_blk;
+  short *lin_buff;              /* linear input samples */
+  Byte *log_buff;              /* compressed data */
+  short *lon_buff;              /* quantized output samples */
+  char inpfil[127], outfil[127];
+  FILE *Fi, *Fo;
+  int inp, out;
+  char law[4], lilo[8];
+  short inp_type, out_type;
+  char revert_even_bits = 1;
+  clock_t t1, t2;               /* aux. for CPU-time measurement */
+#ifdef VMS
+  char mrs[15];                 /* for correct mrs in VMS environment */
+#endif
+  long start_byte, skip = 0;
+
+/*
+ * GETTING PARAMETERS
+ */
+  /* Get options */
+  if (argc < 2)
+    display_usage();
+  else {
+    while (argc > 1 && argv[1][0] == '-')
+      if (argv[1][1] == 'r') {
+        /* Disable revertion of even bits */
+        revert_even_bits = 0;
+
+        /* Move argv over the option to the 1st mandatory argument */
+        argv++;
+
+        /* Update argc */
+        argc--;
+      } else if (strcmp(argv[1], "-skip") == 0) {
+        /* Get skip length */
+        skip = atol(argv[2]);
+
+        /* Check bounds */
+        if (skip < 0) {
+          fprintf(stderr, "Skip has to be > 0!\n");
+          exit(10);
+        }
+
+        /* Move argv over the option to the next argument */
+        argv += 2;
+
+        /* Update argc */
+        argc -= 2;
+      } else if (argv[1][1] == '?') {
+        /* Display intructions */
+        display_usage();
+      } else {
+        fprintf(stderr,
+          "ERROR! Invalid option \"%s\" in command line\n\n", argv[1]);
+        display_usage();
+      }
+  }
+
+
+  /* Get parameters */
+  GET_PAR_S(1, "_Law (A, u): ................. ", law);
+  GET_PAR_S(2, "_Transf (lili,lilo,loli): .... ", lilo);
+  GET_PAR_S(3, "_File to be converted: ....... ", inpfil);
+  GET_PAR_S(4, "_Output File: ................ ", outfil);
+  FIND_PAR_L(5, "_Block Length: ............... ", N, 256);
+  FIND_PAR_L(6, "_Start Block: ................ ", N1, 1);
+  FIND_PAR_L(7, "_No. of Blocks: .............. ", N2, 0);
+
+
+  /* ......... SOME INITIALIZATIONS ......... */
+  --N1;
+
+  /* Classification of the conversion desired */
+  inp_type = toupper(lilo[1]) == 'O' ? IS_LOG : IS_LIN;
+  out_type = toupper(lilo[3]) == 'O' ? IS_LOG : IS_LIN;
+  if ((out_type == IS_LOG) && (inp_type == IS_LOG))
+    HARAKIRI("log. to log. makes no sense! Aborted...\n", 8);
+
+  /* Classification of law */
+  law[0] = toupper(law[0]);
+  if ((law[0] != (char) 'A') && (law[0] != (char) 'U'))
+    HARAKIRI(" Invalid law!\n", 7);
+
+  /* .......... ALLOCATION OF BUFFERS .......... */
+
+  if ((lin_buff = (short *) calloc(N, sizeof(short))) == NULL)
+    HARAKIRI("Can't allocate memory for input buffer\n", 10);
+
+  if ((log_buff = (Byte *) calloc(N, sizeof(Byte))) == NULL)
+    HARAKIRI("Can't allocate memory for output buffer\n", 10);
+
+  if ((lon_buff = (short *) calloc(N, sizeof(short))) == NULL)
+    HARAKIRI("Can't allocate memory for temporary buffer\n", 10);
+
+
+  /* .......... FILE OPERATIONS .......... */
+
+#ifdef VMS
+  sprintf(mrs, "mrs=%d", 2 * N);
+#endif
+
+  /* Open input file */
+  if ((Fi = fopen(inpfil, RB)) == NULL)
+    KILL(inpfil, 2);
+  inp = fileno(Fi);
+
+  /* Open (create) output file */
+  if ((Fo = fopen(outfil, WB)) == NULL)
+    KILL(outfil, 3);
+  out = fileno(Fo);
+
+  /* Define starting byte in file */
+  start_byte = (N1 * N + skip) * sizeof(short);
+
+  /* ... and move file's pointer to 1st desired block */
+  if (fseek(Fi, (N1 * N + skip) * sizeof(short), 0) < 0l)
+    KILL(inpfil, 4);
+
+  /* Check whether is to process til end-of-file */
+  if (N2 == 0) {
+    struct stat st;
+    /* ... hey, need to skip the delayed samples! ... */
+    stat(inpfil, &st);
+    N2 = ceil((st.st_size - start_byte) / (double) (N * sizeof(short)));
+  }
+
+
+/*
+ * ......... COMPRESSION/EXPANSION .........
+ */
+  t1 = clock();                 /* measure CPU-time */
+  tot_smpno = 0;
+
+  switch (law[0]) {
+    /* ......... Process A-law rule ......... */
+  case 'A':
+
+    /* Input: LINEAR | Output: LOG */
+    if (inp_type == IS_LIN && out_type == IS_LOG)
+      for (tot_smpno = cur_blk = 0; cur_blk < N2;
+        cur_blk++, tot_smpno += smpno) {
+        if ((smpno = fread(lin_buff, sizeof(short), N, Fi)) < 0)
+          KILL(inpfil, 5);
+        alaw_compress(smpno, lin_buff, log_buff);
+        if (!revert_even_bits)
+          for (i = 0; i < smpno; i++)
+            log_buff[i] ^= 0x0055;
+
+        if ((smpno = fwrite(log_buff, sizeof(Byte), smpno, Fo)) < 0)
+          KILL(outfil, 6);
+      }
+
+    /* Input: LINEAR | Output: LINEAR */
+    else if (inp_type == IS_LIN && out_type == IS_LIN)
+      for (tot_smpno = cur_blk = 0; cur_blk < N2;
+        cur_blk++, tot_smpno += smpno) {
+        if ((smpno = fread(lin_buff, sizeof(short), N, Fi)) < 0)
+          KILL(inpfil, 5);
+        alaw_compress(smpno, lin_buff, log_buff);
+        alaw_expand(smpno, log_buff, lon_buff);
+        if ((smpno = fwrite(lon_buff, sizeof(short), smpno, Fo)) < 0)
+          KILL(outfil, 6);
+      }
+
+    /* Input: LOG | Output: LINEAR */
+    else if (inp_type == IS_LOG)
+      for (tot_smpno = cur_blk = 0; cur_blk < N2;
+        cur_blk++, tot_smpno += smpno) {
+        if ((smpno = fread(log_buff, sizeof(Byte), N, Fi)) < 0)
+          KILL(inpfil, 5);
+        if (!revert_even_bits)
+          for (i = 0; i < smpno; i++)
+            log_buff[i] ^= 0x0055;
+        alaw_expand(smpno, log_buff, lon_buff);
+        if ((smpno = fwrite(lon_buff, sizeof(short), smpno, Fo)) < 0)
+          KILL(outfil, 6);
+      }
+    break;
+
+    /* ......... Process u-law rule ......... */
+
+  case 'U':
+    /* Input: LINEAR | Output: LOG */
+    if (inp_type == IS_LIN && out_type == IS_LOG)
+      for (tot_smpno = cur_blk = 0; cur_blk < N2;
+        cur_blk++, tot_smpno += smpno) {
+        smpno = fread(lin_buff, sizeof(short), N, Fi);
+        ulaw_compress(smpno, lin_buff, log_buff);
+        smpno = fwrite(log_buff, sizeof(Byte), smpno, Fo);
+      }
+
+    /* Input: LINEAR | Output: LINEAR */
+    else if (inp_type == IS_LIN && out_type == IS_LIN)
+      for (tot_smpno = cur_blk = 0; cur_blk < N2;
+        cur_blk++, tot_smpno += smpno) {
+        smpno = fread(lin_buff, sizeof(short), N, Fi);
+        ulaw_compress(smpno, lin_buff, log_buff);
+        ulaw_expand(smpno, log_buff, lon_buff);
+        smpno = fwrite(lon_buff, sizeof(short), smpno, Fo);
+      }
+
+    /* Input: LOG | Output: LINEAR */
+    else if (inp_type == IS_LOG)
+      for (tot_smpno = cur_blk = 0; cur_blk < N2;
+        cur_blk++, tot_smpno += smpno) {
+        smpno = fread(log_buff, sizeof(Byte), N, Fi);
+        ulaw_expand(smpno, log_buff, lon_buff);
+        smpno = fwrite(lon_buff, sizeof(short), smpno, Fo);
+      }
+    break;
+  }
+
+
+  /* ......... FINALIZATIONS ......... */
+
+  t2 = clock();
+  printf("Speed: %f sec CPU-time for %ld processed samples\n",
+    (t2 - t1) / (double) CLOCKS_PER_SEC, tot_smpno);
+
+  fclose(Fi);
+  fclose(Fo);
+#ifndef VMS
+  return (0);
+#endif
+}

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.