diff intercom/gsm/rpedemo.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/gsm/rpedemo.c	Fri Jun 25 09:57:52 2010 +0200
@@ -0,0 +1,457 @@
+/*                                                         v1.1 - 22/Feb/1996
+  ============================================================================
+
+  RPEDEMO.C
+  ~~~~~~~~~~
+
+  Description:
+  ~~~~~~~~~~~~
+
+  Demonstration program for UGST/ITU-T RPE-LTP module. Takes the
+  input file and processes by the GSM 06.10 Full Rate speech codec,
+  depending on user's option: for encoding, input must be in
+  either linear, A, mu law (G711); for decoding, in GSM 06.10 76-word
+  format. The modules called have been written in Unix-C by Jutta 
+  Deneger and Carsten Borman, within the Communications and 
+  Operating Systems Research Group (KBS) of the Technishe Universitaet 
+  Berlin. This demo program has been written by Simao F.Campos Neto,
+  from CPqD/Telebras based on previous UGST demo programs, as well on
+  a driving program by the RPE-LTP program.
+
+  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 RPE-LTP data will use a
+  varied number of least significant bits. Both are without sign
+  extension. Linear format, on its hand, expect data to be 16-bit
+  aligned to the left, and the algorith will take only the 13 most
+  significant bits. This complies to the general UGST integer data
+  format.
+
+  Output data will be generated in the same format as decribed
+  above for the input data.
+
+  Usage:
+  ~~~~~~
+  $ rpedemo [-l|-u|-A] [-enc|-dec]  InpFile OutFile BlockSize 1stBlock
+             NoOfBlocks 
+  where:
+   -l .......... input data for encoding and output data for decoding
+                 are in linear format (DEFAULT).
+   -A .......... input data for encoding and output data for decoding
+                 are in A-law (G.711) format.
+   -u .......... input data for encoding and output data for decoding
+                 are in u-law (G.711) format.
+   -enc ........ run the only the decoder (default: run enc+dec)
+   -dec ........ run the only the encoder (default: run enc+dec)
+   
+   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 (default = 160)
+   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"
+
+  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 creating gsm object (i.e., state variable);
+  6        error reading input file;
+  7        error writing to file;
+
+  Original authors:
+  ~~~~~~~~~~~~~~~~~
+  Demo program:
+  Simao Ferraz de Campos Neto   EMail : simao@cpqd.ansp.br
+  CPqD/Telebras                 Rd. Mogi Mirim-Campinas Km.118
+  DDS/Pr.11                     13.088-061 - Campinas - SP (Brazil)
+
+  Module routines:
+  Jutta Degener (jutta@cs.tu-berlin.de)
+  Carsten Bormann (cabo@cs.tu-berlin.de)
+
+  History:
+  ~~~~~~~~
+  28/Oct/92 r.1.0 pl.0 by  Carsten Bormann  (cabo at kubus)
+        Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
+        Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
+        details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
+
+  30/Oct/92 r.1.0 pl.1 by Jutta Degener  (jutta at kraftbus)
+        Switched uid/gid in toast's [f]chown calls.
+
+  29/Jan/93 r.1.0 pl.2 by Jutta Degener  (jutta at kraftbus)
+        fixed L_add(0,-1) in src/add.c and inc/private.h,
+        thanks to Raphael Trommer at AT&T Bell Laboratories;
+        * ANSI C compatibility details
+
+  20/Mar/94 v1.0 Release of 1st version of demo program
+
+  22/Feb/95 v1.1 Cleaned compilation warnings, modified for Alpha VMX/AXP 
+                 operation (as suggested by Kirchherr, FI/DBP Telekom)
+		 <simao@ctd.comsat.com>
+  ============================================================================
+*/
+
+
+/* ..... General definitions for UGST demo programs ..... */
+#include "ugstdemo.h"
+
+/* ..... General include ..... */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(VMS)
+#include <stat.h>
+#else                           /* Unix/DOS */
+#include <sys/stat.h>
+#endif
+
+/* ..... RPE-LTP module definitions ..... */
+#include "private.h"
+#include "gsm.h"
+#include "rpeltp.h"
+
+/* ..... G.711 module definitions ..... */
+#include "g711.h"
+
+/* ..... Local definitions ..... */
+#define LINEAR 0                /* binary: 00 */
+#define U_LAW 1                 /* binary: 01 */
+#define A_LAW 3                 /* binary: 11 */
+
+/* ..... Local function prototypes ..... */
+void display_usage ARGS((void));
+int main ARGS((int argc, char *argv[]));
+
+
+/*
+ -------------------------------------------------------------------------
+ void display_usage(void);
+ ~~~~~~~~~~~~~~~~~~
+ Display proper usage for the demo program. Generated automatically from
+ program documentation.
+
+ History:
+ ~~~~~~~~
+ 20.Mar.94 v1.0 Created.
+ -------------------------------------------------------------------------
+*/
+#define P(x) printf x
+void display_usage()
+{
+  P(("RPEDEMO: Version 1.0 of 17/Mar/1994 \n\n"));
+
+  P(("  Demonstration program for UGST/ITU-T RPE-LTP based on \n"));
+  P(("  module implemented  in Unix-C by Jutta Deneger and Carsten \n"));
+  P(("  Borman, within the Communications and Operating Systems \n"));
+  P(("  Research Group (KBS) of the Technishe Universitaet Berlin.\n"));
+  P(("  This demo program has been written by Simao F.Campos Neto\n"));
+  P(("\n"));
+  P(("  Usage:\n"));
+  P(("  $ rpedemo [-l|-u|-A] [-enc|-dec]  InpFile OutFile BlockSize 1stBlock\n"));
+  P(("             NoOfBlocks \n"));
+  P(("  where:\n"));
+  P(("   -l .......... input data for encoding and output data for decoding\n"));
+  P(("                 are in linear format (DEFAULT).\n"));
+  P(("   -A .......... input data for encoding and output data for decoding\n"));
+  P(("                 are in A-law (G.711) format.\n"));
+  P(("   -u .......... input data for encoding and output data for decoding\n"));
+  P(("                 are in u-law (G.711) format.\n"));
+  P(("   -enc ........ run the only the decoder (default: run enc+dec)\n"));
+  P(("   -dec ........ run the only the encoder (default: run enc+dec)\n"));
+  P(("\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 (default = 160)\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"));
+
+  /* Quit program */
+  exit(-128);
+}
+
+#undef P
+
+/*
+   **************************************************************************
+   ***                                                                    ***
+   ***        Demo-Program for testing the correct implementation         ***
+   ***               and to show how to use the programs                  ***
+   ***                                                                    ***
+   **************************************************************************
+*/
+main(argc, argv)
+int argc;
+char *argv[];
+{
+  gsm rpe_enc_state, rpe_dec_state;
+  gsm_signal rpe_frame[RPE_FRAME_SIZE];
+  Byte gsm_frame[33];
+  long N = 256, N1 = 1, N2 = 0, cur_blk, smpno, count = 0;
+#ifdef STATIC_ALLOCATION
+  short tmp_buf[256], inp_buf[256], out_buf[256];
+#else
+  short *tmp_buf, *inp_buf, *out_buf;
+#endif
+
+  /* G.711 Compression/expansion function pointers */
+  void (*compress) (), (*expand) ();
+
+  /* File variables */
+  char FileIn[80], FileOut[80];
+  FILE *Fi, *Fo;
+  long start_byte;
+  char format, run_encoder, run_decoder;
+#ifdef VMS
+  char mrs[15];
+#endif
+
+
+  /* SETTING DEFAULT OPTIONS */
+  format = LINEAR;
+  run_encoder = run_decoder = 1;
+
+  /* GETTING OPTIONS */
+
+  if (argc < 2)
+    display_usage();
+  else {
+    while (argc > 1 && argv[1][0] == '-')
+      if (strcmp(argv[1], "-") == 0) {
+        /* Oops, stop processing options! */
+        break;
+      } else if (strcmp(argv[1], "-l") == 0) {
+        /* Input/output (uncoded) data format is linear */
+        format = LINEAR;
+
+        /* Move arg[cv] over the next valid option */
+        argv++;
+        argc--;
+      } else if (strcmp(argv[1], "-A") == 0
+        || strcmp(argv[1], "-a") == 0) {
+        /* Input/output (uncoded) data format is A-law (G.711) */
+        format = A_LAW;
+
+        /* Move arg[cv] over the next valid option */
+        argv++;
+        argc--;
+      } else if (strcmp(argv[1], "-u") == 0) {
+        /* Input/output (uncoded) data format is u-law (G.711) */
+        format = U_LAW;
+
+        /* Move arg[cv] over the next valid option */
+        argv++;
+        argc--;
+      } else if (strcmp(argv[1], "-enc") == 0) {
+        /* Run only the encoder */
+        run_encoder = 1;
+        run_decoder = 0;
+
+        /* Move arg[cv] over the next valid option */
+        argv++;
+        argc--;
+      } else if (strcmp(argv[1], "-dec") == 0) {
+        /* Run only the encoder */
+        run_encoder = 0;
+        run_decoder = 1;
+
+        /* Move arg[cv] over the next valid option */
+        argv++;
+        argc--;
+      } else {
+        fprintf(stderr,
+          "ERROR! Invalid option \"%s\" in command line\n\n", argv[1]);
+        display_usage();
+      }
+  }
+
+  GET_PAR_S(1, "_Input File: .................. ", FileIn);
+  GET_PAR_S(2, "_Output File: ................. ", FileOut);
+  FIND_PAR_L(3, "_Block Size: .................. ", N, RPE_WIND_SIZE);
+  FIND_PAR_L(4, "_Starting Block: .............. ", N1, 1);
+  FIND_PAR_L(5, "_No. of Blocks: ............... ", N2, 0);
+
+
+  /* Find staring byte in file; all are 16-bit word-aligned =>short data type */
+  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);
+    /* convert to block count, depending on whether the input file 
+     * is a uncoded or coded file */
+    if (run_encoder)
+      N2 = (st.st_size - start_byte) / (N * sizeof(short));
+    else
+      N2 = (st.st_size - start_byte) / (33 * sizeof(Byte));
+  }
+
+  /* Choose A/u law */
+  if (format == A_LAW) {
+    expand = alaw_expand;
+    compress = alaw_compress;
+  } else if (format == U_LAW) {
+    expand = ulaw_expand;
+    compress = ulaw_compress;
+  }
+
+
+/*
+ * ...... MEMORY ALLOCATION .........
+ */
+#ifndef STATIC_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);
+#endif
+
+
+/*
+ * ......... FILE PREPARATION .........
+ */
+
+  /* Define stuff for VMS binary, fixed-record files */
+#ifdef VMS
+  sprintf(mrs, "mrs=%d", 512);
+#endif
+
+  /* Opening input/output files; abort if there's any problem */
+  if ((Fi = fopen(FileIn, RB)) == NULL)
+    KILL(FileIn, 2);
+
+  if ((Fo = fopen(FileOut, WB)) == NULL)
+    KILL(FileOut, 3);
+
+  /* Move pointer to 1st block of interest */
+  if (fseek(Fi, start_byte, 0) < 0l)
+    KILL(FileIn, 4);
+
+  /* ......... CREATE AND INIT GSM OBJECT (STATE VARIABLE) ......... */
+  if (!(rpe_enc_state = rpeltp_init()))
+    HARAKIRI("Error creating state variable for encoder\n", 5);
+  if (!(rpe_dec_state = rpeltp_init()))
+    HARAKIRI("Error creating state variable for encoder\n", 5);
+
+
+  /* ......... PROCESSING ACCORDING TO GSM 06.10 RPE-LTP CODEC ......... */
+
+  for (cur_blk = 0; cur_blk < N2; cur_blk++) {
+    /* Reset output sample vector */
+    memset(out_buf, (int) 0, N);
+
+    /* Read a block of samples */
+    if (run_encoder) {
+      /* Reset sample vector */
+      memset(inp_buf, (int) 0, N);
+
+      /* Read a block of uncoded samples */
+      if ((smpno = fread(inp_buf, sizeof(short), (long) N, Fi)) <= 0)
+        break;
+    } else {
+      /* Reset frame vector */
+      memset(rpe_frame, (int) 0, (long) RPE_FRAME_SIZE);
+
+      /* Read a packed frame */
+      if ((smpno = fread(gsm_frame, sizeof(Byte), 33, Fi)) <= 0) {
+        fprintf(stderr, "fread gsm_frame\n");
+        break;
+      }
+    }
+
+    /* Carry out the desired operation */
+
+    /* CODEC OPERATION */
+    if (run_encoder && run_decoder) {
+      /* Run both and save decoded samples */
+
+      /* First, expand samples, if needed */
+      if (format) {
+        memcpy(tmp_buf, inp_buf, (long) (sizeof(short) * smpno));
+        expand(smpno, tmp_buf, inp_buf);
+      }
+
+      /* Encode & decode ... */
+      rpeltp_encode(rpe_enc_state, inp_buf, rpe_frame);
+      rpeltp_decode(rpe_dec_state, rpe_frame, out_buf);
+
+      /* Compress samples, if requested */
+      if (format) {
+        memcpy(tmp_buf, out_buf, (long) (sizeof(short) * N));
+        compress(N, tmp_buf, out_buf);
+      }
+
+      /* Save samples to file */
+      if (!(smpno = fwrite(out_buf, sizeof(short), (long) smpno, Fo)))
+        break;
+    }
+    /* ENCODER-ONLY OPERATION */
+    else if (run_encoder) {
+      
+      /* First, expand samples, if needed */
+      if (format) {
+        memcpy(tmp_buf, inp_buf, (long) (sizeof(short) * smpno));
+        expand(smpno, tmp_buf, inp_buf);
+      }
+
+      /* Run only the encoder and save rpe-ltp frame */
+      gsm_encode(rpe_enc_state, inp_buf, gsm_frame);
+      
+      if (!(smpno =
+          fwrite(gsm_frame, sizeof(Byte), 33, Fo)))
+        break;
+    }
+    /* DECODER-ONLY OPERATION */
+    else {
+      /* Decode frame */
+      gsm_decode(rpe_dec_state, gsm_frame, out_buf);
+
+      /* Compress samples, if requested */
+      if (format) {
+        memcpy(tmp_buf, out_buf, (long) (sizeof(short) * N));
+        compress(N, tmp_buf, out_buf);
+      }
+
+      /* Save the decoded samples */
+      if (!(smpno = fwrite(out_buf, sizeof(short), (long) N, Fo)))
+        break;
+    }
+    count += smpno;
+  }
+
+  /* Check for errors */
+  if (ferror(Fi))
+    KILL(FileIn, 6);
+  else if (ferror(Fo))
+    KILL(FileOut, 7);
+
+  /* ......... FINALIZATIONS ......... */
+
+  /* Close input and output files and state */
+  fclose(Fi);
+  fclose(Fo);
+  rpeltp_delete(rpe_enc_state);
+  rpeltp_delete(rpe_dec_state);
+
+  /* Exit with success for non-vms systems */
+#ifndef VMS
+  return (0);
+#endif
+}
+
+/* ............................. end of main() ............................. */

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