diff intercom/g726/g726demo.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/g726/g726demo.c	Fri Jun 25 09:57:52 2010 +0200
@@ -0,0 +1,392 @@
+/*                                                           21/Mar/2000 V1.2
+  ============================================================================
+
+  G726DEMO.C
+  ~~~~~~~~~~
+
+  Description:
+  ~~~~~~~~~~~~
+
+  Demonstration program for UGST/ITU-T G.726 module (the same as the Blue 
+  Book G.726). Takes the input file and processes by the G.726 codec, 
+  depending on user's option: for encoding, input must be in either A 
+  or mu law (G711), for decoding, in ADPCM format. The modules called have 
+  been originally written in Fortran, and were translated into C by the 
+  converter f2c, version of October 15, 1990 at 19:58:17.
+
+  Input data is supposed to be aligned at word boundaries, i.e.,
+  organized in 16-bit words, following the operating system normal
+  organization (low-byte first for VMS and DOS; high byte first
+  for most Unix systems). G711 compressed data is supposed to be
+  in the 8 LEAST significant bits of the word and the ADPCM data
+  is in the LEAST 5 bits. Both are without sign extension.
+
+  Output data will be generated in the same format as decribed
+  above for the input data.
+
+  Usage:
+  ~~~~~~
+  $ G726demo [-options] Law Transf Rate InpFile OutFile 
+  [BlockSize [1stBlock [NoOfBlocks [Reset]]]]
+  where:
+   Law       is the law desired (either A or u)
+  Transf     is the desired conversion on the input file:
+              [lolo], (A/u)log -> ADPCM -> (A/u) log
+	      [load], (A/u)log -> ADPCM
+	      [adlo], ADPCM    -> (A/u) log
+  Rate       is the number of ADPCM bits per sample:
+              [5],[40] -> 5 bits per sample (40 kbit/s)
+	      [4],[32] -> 4 bits per sample (32 kbit/s)
+	      [3],[24] -> 3 bits per sample (24 kbit/s)
+	      [2],[16] -> 2 bits per sample (16 kbit/s)
+  InpFile     is the name of the file to be processed;
+  OutFile     is the name with the processed data;
+  BlockSize   is the block size, in number of samples
+  1stBlock    is the number of the first block of the input file
+              to be processed;
+  NoOfBlocks  is the number of blocks to be processed, starting on
+              block "1stBlock"
+  Reset       is the optional reset. If specified as 1, the
+              coder and decoder will be reset at the very beginning of
+	      the processings. If 0, the processing will start with
+	      the variables at a unknown state. It defaults to 1
+	      (reset ON).
+  Options:
+  -noreset    don't apply reset to the encoder/decoder
+  -?/-help    print help message
+        
+
+  Example:
+  $ G726demo u lolo  4 voice.ref voice.rel 256 3 45 *OR*
+  $ G726demo u lolo 32 voice.ref voice.rel 256 3 45
+  
+  The command above takes the samples in file "voice.ref", already
+  in mu law format, processes the data through the G726 encoder
+  and decoder at a rate of 32 bkit/s,  saving them into the file
+  "voice.rel". The processing starts  at block 3 for 45 blocks,
+  each block being 256 samples wide.
+
+  Original authors:
+  ~~~~~~~~~~~~~~~~~
+  Simao Ferraz de Campos Neto   EMail : simao@cpqd.ansp.br (32k)
+  Fernando Tofolli Queiroz      EMail : tdfernan@cpqd.ansp.br (extension)
+
+  CPqD/Telebras                 Rd. Mogi Mirim-Campinas Km.118
+  DDS/Pr.11                     13.088-061 - Campinas - SP (Brazil)
+
+  History:
+  ~~~~~~~~
+  28/Feb/1994 v1.0 Release of 1st version of this demo program
+                   based on the g721demo of the STL92. G.726
+                   functionality added by Fernando Toffoli Queiroz
+                   <tdfernan@cpqd.ansp.br>; usage routine and
+                   portability tests by Simao.
+  22/Feb/1996 v1.1 Removed compilation warnings, included headers as
+                   suggested by Kirchherr (FI/DBP Telekom) to run under
+		   OpenVMS/AXP <simao@ctd.comsat.com>
+  21/Mar/2000 v1.2 Changed memory allocation of floating point buffers
+                   tmp_buf[], inp_buf[] and out_buf[] from static to
+                   dynamic, to prevent memory invasion
+		   when block sizes larger than 256 are specified. 
+                   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>
+
+============================================================================ 
+*/
+
+
+/* ..... General definitions for UGST demo programs ..... */
+#include "ugstdemo.h"
+
+/* ..... General include ..... */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <math.h>
+
+#if defined(VMS)
+#include <stat.h>
+#else                           /* Unix/DOS */
+#include <sys/stat.h>
+#endif
+
+/* ..... G.726 module as include functions ..... */
+#include "g726.h"
+
+/*
+ -------------------------------------------------------------------------
+ void display_usage(void);
+ ~~~~~~~~~~~~~~~~~~
+ Display proper usage for the demo program. Generated automatically from
+ program documentation.
+
+ History:
+ ~~~~~~~~
+ 8.Mar.94 v1.0 Created.
+ -------------------------------------------------------------------------
+*/
+#define P(x) printf x
+void display_usage()
+{
+  P(("G726DEMO - Version 1.2 of 21/Mar/2000 \n\n"));
+
+  P(("> Description:\n"));
+  P(("   Demonstration program for UGST/ITU-T G.726 module. Takes the\n"));
+  P(("   input file and processes by the G.726 codec,\n"));
+  P(("   depending on user's option: for encoding, input must be in\n"));
+  P(("   either A or mu law (G711), for decoding, in ADPCM format. The\n"));
+  P(("   modules called have been originally written in Fortran, and were\n"));
+  P(("   translated into C by the converter f2c, version of October 15,1990\n"));
+  P(("\n"));
+  P(("   Input data is supposed to be aligned at word boundaries, i.e.,\n"));
+  P(("   organized in 16-bit words, following the operating system normal\n"));
+  P(("   organization (low-byte first for VMS and DOS; high byte first\n"));
+  P(("   for most Unix systems). G711 compressed data is supposed to be\n"));
+  P(("   in the 8 LEAST significant bits of the word and the ADPCM data\n"));
+  P(("   is in the LEAST 5 bits. Both are without sign extension.\n"));
+  P(("\n"));
+  P(("   Output data will be generated in the same format as decribed\n"));
+  P(("   above for the input data.\n"));
+  P(("\n"));
+
+  P(("> Usage:\n"));
+  P(("$ G726demo [-options] Law Transf Rate InpFile OutFile \n"));
+  P(("           [BlockSize [1stBlock [NoOfBlocks [Reset]]]]\n"));
+  P((" where:\n"));
+  P((" Law         is the law desired (either A or u)\n"));
+  P((" Transf      is the desired conversion on the input file:\n"));
+  P(("              [lolo], (A/u)log -> ADPCM -> (A/u) log\n"));
+  P(("              [load], (A/u)log -> ADPCM  \n"));
+  P(("              [adlo], ADPCM    -> (A/u) log\n"));
+  P((" Rate        is the number of ADPCM bits per sample:\n"));
+  P(("              [5],[40] -> 5 bits per sample (40 kbit/s)\n"));
+  P(("              [4],[32] -> 4 bits per sample (32 kbit/s)\n"));
+  P(("              [3],[24] -> 3 bits per sample (24 kbit/s)\n"));
+  P(("              [2],[16] -> 2 bits per sample (16 kbit/s)\n"));
+  P((" InpFile     is the name of the file to be processed;\n"));
+  P((" OutFile     is the name with the processed data;\n"));
+  P((" BlockSize   is the block size, in number of samples\n"));
+  P((" 1stBlock    is the number of the first block of the input file\n"));
+  P(("             to be processed;\n"));
+  P((" NoOfBlocks  is the number of blocks to be processed, starting on\n"));
+  P(("             block \"1stBlock\"\n"));
+  P((" Reset       is the optional reset. If specified as 1, the\n"));
+  P(("             coder and decoder will be  reset at the very\n"));
+  P(("             beginning of the processings. If 0, the\n"));
+  P(("             processing will start with the variables  at a\n"));
+  P(("             unknown state. It defaults to 1 (reset ON). \n"));
+  P((" Options: \n"));
+  P((" -noreset    don't apply reset to the encoder/decoder\n"));
+  P((" -? or -help print this help message\n"));
+  P(("\n"));
+
+  /* Quit program */
+  exit(-128);
+}
+
+#undef P
+/* .................... 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[];
+{
+  G726_state encoder_state, decoder_state;
+  long N = 256, N1 = 1, N2 = 0, cur_blk, smpno;
+  short *tmp_buf, *inp_buf, *out_buf, reset = 1;
+  short inp_type, out_type, rate;
+
+  /* Progress indication */
+  static char quiet = 0, funny[9] = "|/-\\|/-\\";
+
+/* File variables */
+  char FileIn[80], FileOut[80], law[4], lilo[8];
+  FILE *Fi, *Fo;
+  int inp, out;
+  long start_byte;
+#ifdef VMS
+  char mrs[15];
+#endif
+
+/*
+ * ......... PARAMETERS FOR PROCESSING .........
+ */
+
+  /* GETTING OPTIONS */
+
+  if (argc < 2)
+    display_usage();
+  else {
+    while (argc > 1 && argv[1][0] == '-')
+      if (strcmp(argv[1], "-noreset") == 0) {
+        /* No reset */
+        reset = 0;
+
+        /* Update argc/argv to next valid option/argument */
+        argv++;
+        argc--;
+      } else if (strcmp(argv[1], "-q") == 0) {
+        /* Don't print progress indicator */
+        quiet = 1;
+
+        /* Move argv over the option to the next argument */
+        argv++;
+        argc--;
+      } else if (strcmp(argv[1], "-?") == 0
+        || strcmp(argv[1], "-help") == 0) {
+        /* Print help */
+        display_usage();
+      } else {
+        fprintf(stderr,
+          "ERROR! Invalid option \"%s\" in command line\n\n", argv[1]);
+        display_usage();
+      }
+  }
+
+  /* Now get regular parameters */
+  GET_PAR_S(1, "_Law (A,u): ................... ", law);
+  GET_PAR_S(2, "_Operation (lolo,load,adlo): .. ", lilo);
+  GET_PAR_I(3, "_Rate or bits/ADPCM sample: ... ", rate);
+  GET_PAR_S(4, "_Input File: .................. ", FileIn);
+  GET_PAR_S(5, "_Output File: ................. ", FileOut);
+  FIND_PAR_L(6, "_Block Size: .................. ", N, 256);
+  FIND_PAR_L(7, "_Starting Block: .............. ", N1, 1);
+  FIND_PAR_L(8, "_No. of Blocks: ............... ", N2, 0);
+  FIND_PAR_I(9, "_Reset (YES=1, NO=0): ......... ", reset, 1);
+
+  /* Find starting byte in file */
+  start_byte = sizeof(short) * (long) (--N1) * (long) N;
+
+  /* Check if is to process the whole file */
+  if (N2 == 0) {
+    struct stat st;
+
+    /* ... find the input file size ... */
+    stat(FileIn, &st);
+    N2 = ceil((st.st_size - start_byte) / (double) (N * sizeof(short)));
+  }
+
+  /* Classification of the conversion desired */
+  inp_type = toupper(lilo[1]) == 'O' ? IS_LOG : IS_ADPCM;
+  out_type = toupper(lilo[3]) == 'O' ? IS_LOG : IS_ADPCM;
+  if ((out_type == IS_ADPCM) && (inp_type == IS_ADPCM))
+    HARAKIRI("Bad conversion chosen (lolo,load,adlo)! Aborted...\n", 8);
+
+  /* Classification of law */
+  if (toupper(law[0]) == (char) 'A')
+    law[0] = '1';
+  else if (toupper(law[0]) == (char) 'U')
+    law[0] = '0';
+  else
+    HARAKIRI(" Invalid law (A or u)! Aborted...\n", 7);
+
+  /* Classification of rate */
+  if (rate > 5) {
+    if (rate == 40)
+      rate = 5;
+    else if (rate == 32)
+      rate = 4;
+    else if (rate == 24)
+      rate = 3;
+    else if (rate == 16)
+      rate = 2;
+    else {
+      HARAKIRI(" Invalid rate (5/4/3/2) or (40/32/24/16)! Aborted...\n",
+        9);
+    }
+  }
+
+/*
+ * ...... MEMORY ALLOCATION .........
+ */
+
+  if ((inp_buf = (short *) calloc(N, sizeof(short))) == NULL)
+    HARAKIRI("Error in memory allocation!\n", 1);
+  if ((out_buf = (short *) calloc(N, sizeof(short))) == NULL)
+    HARAKIRI("Error in memory allocation!\n", 1);
+  if ((tmp_buf = (short *) calloc(N, sizeof(short))) == NULL)
+    HARAKIRI("Error in memory allocation!\n", 1);
+
+/*
+ * ......... FILE PREPARATION .........
+ */
+
+  /* Opening input file; abort if there's any problem */
+  if ((Fi = fopen(FileIn, "rb")) == NULL)
+    KILL(FileIn, 2);
+  inp = fileno(Fi);
+
+  /* Creates output file */
+#ifdef VMS
+  sprintf(mrs, "mrs=%d", 512);
+#endif
+  if ((Fo = fopen(FileOut, WB)) == NULL)
+    KILL(FileOut, 3);
+  out = fileno(Fo);
+
+  /* Move pointer to 1st block of interest */
+  if (fseek(Fi, start_byte, 0) < 0l)
+    KILL(FileIn, 4);
+
+/*
+ * ......... PROCESSING ACCORDING TO ITU-T G.726 .........
+ */
+
+  for (cur_blk = 0; cur_blk < N2; cur_blk++) {
+    /* Print progress flag */
+    if (!quiet)
+      fprintf(stderr, "%c\r", funny[cur_blk % 8]);
+
+    /* Read a block of samples */
+    if ((smpno = fread(inp_buf, sizeof(short), N, Fi)) < 0)
+      KILL(FileIn, 5);
+
+    /* Check if reset is needed */
+    reset = (reset == 1 && cur_blk == 0) ? 1 : 0;
+
+    /* Carry out the desired operation */
+    if (inp_type == IS_LOG && out_type == IS_ADPCM) {
+      G726_encode(inp_buf, out_buf, smpno, law, rate, reset,
+        &encoder_state);
+    } else if (inp_type == IS_ADPCM && out_type == IS_LOG) {
+      G726_decode(inp_buf, out_buf, smpno, law, rate, reset,
+        &decoder_state);
+    } else if (inp_type == IS_LOG && out_type == IS_LOG) {
+      G726_encode(inp_buf, tmp_buf, smpno, law, rate, reset,
+        &encoder_state);
+      G726_decode(tmp_buf, out_buf, smpno, law, rate, reset,
+        &decoder_state);
+    }
+
+    /* Write ADPCM output word */
+    if ((smpno = fwrite(out_buf, sizeof(short), smpno, Fo)) < 0)
+      KILL(FileOut, 6);
+  }
+
+/*
+ * ......... FINALIZATIONS .........
+ */
+
+  /* Close input and output files */
+  fclose(Fi);
+  fclose(Fo);
+
+  /* Exit with success for non-vms systems */
+#ifndef VMS
+  return (0);
+#endif
+}
+
+/* ............................. end of main() ............................. */

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