diff intercom/g711/g711.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/g711.c	Fri Jun 25 09:57:52 2010 +0200
@@ -0,0 +1,314 @@
+/*                                                 Version 3.01 - 31.Jan.2000
+=============================================================================
+
+                          U    U   GGG    SSS  TTTTT
+                          U    U  G      S       T
+                          U    U  G  GG   SSS    T
+                          U    U  G   G      S   T
+                           UUUU    GGG    SSS    T
+
+                   ========================================
+                    ITU-T - USER'S GROUP ON SOFTWARE TOOLS
+                   ========================================
+
+
+       =============================================================
+       COPYRIGHT NOTE: This source code, and all of its derivations,
+       is subject to the "ITU-T General Public License". Please have
+       it  read  in    the  distribution  disk,   or  in  the  ITU-T
+       Recommendation G.191 on "SOFTWARE TOOLS FOR SPEECH AND  AUDIO 
+       CODING STANDARDS".
+       =============================================================
+
+
+MODULE:	G711.C, G.711 ENCODING/DECODING FUNCTIONS
+
+ORIGINAL BY:
+
+     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.085 - Campinas - SP (Brazil)      D-8500 Nuernberg 10 (Germany)
+
+     Phone : +55-192-39-6396              Phone : +49 911 526-2603
+     FAX   : +55-192-53-4754              FAX   : +49 911 526-3385
+     EMail : tdsimao@venus.cpqd.ansp.br   EMail : HF@PKINBG.UUCP
+
+
+FUNCTIONS:
+
+alaw_compress: ... compands 1 vector of linear PCM samples to A-law;
+                   uses 13 Most Sig.Bits (MSBs) from input and 8 Least
+                   Sig. Bits (LSBs) on output.
+
+alaw_expand: ..... expands 1 vector of A-law samples to linear PCM;
+                   use 8 Least Sig. Bits (LSBs) from input and
+                   13 Most Sig.Bits (MSBs) on output.
+
+ulaw_compress: ... compands 1 vector of linear PCM samples to u-law;
+                   uses 14 Most Sig.Bits (MSBs) from input and 8 Least
+                   Sig. Bits (LSBs) on output.
+
+ulaw_expand: ..... expands 1 vector of u-law samples to linear PCM
+                   use 8 Least Sig. Bits (LSBs) from input and
+                   14 Most Sig.Bits (MSBs) on output.
+
+PROTOTYPES: in g711.h
+
+HISTORY:
+Apr/91       1.0   First version of the G711 module
+10/Dec/1991  2.0   Break-up in individual functions for A,u law;
+                   correction of bug in compression routines (use of 1
+                   and 2 complement); Demo program inside module.
+08/Feb/1992  3.0   Demo as separate file;
+31/Jan/2000  3.01  Updated documentation text; no change in functions 
+                   <simao.campos@labs.comsat.com>
+13jan2005          Byte for compressed data
+=============================================================================
+*/
+
+/*
+ *	.......... I N C L U D E S ..........
+ */
+
+/* Global prototype functions */
+#include "g711.h"
+
+/*
+ *	.......... F U N C T I O N S ..........
+ */
+
+/* ................... Begin of alaw_compress() ..................... */
+/*
+  ==========================================================================
+
+   FUNCTION NAME: alaw_compress
+
+   DESCRIPTION: ALaw encoding rule according ITU-T Rec. G.711.
+
+   PROTOTYPE: void alaw_compress(long lseg, short *linbuf, short *logbuf)
+
+   PARAMETERS:
+     lseg:	(In)  number of samples
+     linbuf:	(In)  buffer with linear samples (only 12 MSBits are taken
+                      into account)
+     logbuf:	(Out) buffer with compressed samples (8 bit right justified,
+                      without sign extension)
+
+   RETURN VALUE: none.
+
+   HISTORY:
+   10.Dec.91	1.0	Separated A-law compression function
+
+  ==========================================================================
+*/
+void alaw_compress(long lseg, short *linbuf, Byte *logbuf)
+{
+  short ix, iexp;
+  long n;
+
+  for (n = 0; n < lseg; n++) {
+    ix = linbuf[n] < 0          /* 0 <= ix < 2048 */
+      ? (~linbuf[n]) >> 4       /* 1's complement for negative values */
+      : (linbuf[n]) >> 4;
+
+    /* Do more, if exponent > 0 */
+    if (ix > 15) {              /* exponent=0 for ix <= 15 */
+      iexp = 1;                 /* first step: */
+      while (ix > 16 + 15) {    /* find mantissa and exponent */
+        ix >>= 1;
+        iexp++;
+      }
+      ix -= 16;                 /* second step: remove leading '1' */
+
+      ix += iexp << 4;          /* now compute encoded value */
+    }
+    if (linbuf[n] >= 0)
+      ix |= (0x0080);           /* add sign bit */
+
+    logbuf[n] = ix ^ (0x0055);  /* toggle even bits */
+  }
+}
+
+/* ................... End of alaw_compress() ..................... */
+
+
+/* ................... Begin of alaw_expand() ..................... */
+/*
+  ==========================================================================
+
+   FUNCTION NAME: alaw_expand
+
+   DESCRIPTION: ALaw decoding rule according ITU-T Rec. G.711.
+
+   PROTOTYPE: void alaw_expand(long lseg, short *logbuf, short *linbuf)
+
+   PARAMETERS:
+     lseg:	(In)  number of samples
+     logbuf:	(In)  buffer with compressed samples (8 bit right justified,
+                      without sign extension)
+     linbuf:	(Out) buffer with linear samples (13 bits left justified)
+
+   RETURN VALUE: none.
+
+   HISTORY:
+   10.Dec.91	1.0	Separated A-law expansion function
+
+  ============================================================================
+*/
+void alaw_expand(long lseg, Byte *logbuf, short *linbuf)
+{
+  short ix, mant, iexp;
+  long n;
+
+  for (n = 0; n < lseg; n++) {
+    ix = logbuf[n] ^ (0x0055);  /* re-toggle toggled bits */
+
+    ix &= (0x007F);             /* remove sign bit */
+    iexp = ix >> 4;             /* extract exponent */
+    mant = ix & (0x000F);       /* now get mantissa */
+    if (iexp > 0)
+      mant = mant + 16;         /* add leading '1', if exponent > 0 */
+
+    mant = (mant << 4) + (0x0008);      /* now mantissa left justified and */
+    /* 1/2 quantization step added */
+    if (iexp > 1)               /* now left shift according exponent */
+      mant = mant << (iexp - 1);
+
+    linbuf[n] = logbuf[n] > 127 /* invert, if negative sample */
+      ? mant : -mant;
+  }
+}
+
+/* ................... End of alaw_expand() ..................... */
+
+
+/* ................... Begin of ulaw_compress() ..................... */
+/*
+  ==========================================================================
+
+   FUNCTION NAME: ulaw_compress
+
+   DESCRIPTION: Mu law encoding rule according ITU-T Rec. G.711.
+
+   PROTOTYPE: void ulaw_compress(long lseg, short *linbuf, short *logbuf)
+
+   PARAMETERS:
+     lseg:	(In)  number of samples
+     linbuf:	(In)  buffer with linear samples (only 12 MSBits are taken
+                      into account)
+     logbuf:	(Out) buffer with compressed samples (8 bit right justified,
+                      without sign extension)
+
+   RETURN VALUE: none.
+
+   HISTORY:
+   10.Dec.91	1.0	Separated mu-law compression function
+
+  ==========================================================================
+*/
+void ulaw_compress(long lseg, short *linbuf, Byte *logbuf)
+{
+  long n;                       /* samples's count */
+  short i;                      /* aux.var. */
+  short absno;                  /* absolute value of linear (input) sample */
+  short segno;                  /* segment (Table 2/G711, column 1) */
+  short low_nibble;             /* low  nibble of log companded sample */
+  short high_nibble;            /* high nibble of log companded sample */
+
+  for (n = 0; n < lseg; n++) {
+    /* -------------------------------------------------------------------- */
+    /* Change from 14 bit left justified to 14 bit right justified */
+    /* Compute absolute value; adjust for easy processing */
+    /* -------------------------------------------------------------------- */
+    absno = linbuf[n] < 0       /* compute 1's complement in case of  */
+      ? ((~linbuf[n]) >> 2) + 33        /* negative samples */
+      : ((linbuf[n]) >> 2) + 33;        /* NB: 33 is the difference value */
+    /* between the thresholds for */
+    /* A-law and u-law. */
+    if (absno > (0x1FFF))       /* limitation to "absno" < 8192 */
+      absno = (0x1FFF);
+
+    /* Determination of sample's segment */
+    i = absno >> 6;
+    segno = 1;
+    while (i != 0) {
+      segno++;
+      i >>= 1;
+    }
+
+    /* Mounting the high-nibble of the log-PCM sample */
+    high_nibble = (0x0008) - segno;
+
+    /* Mounting the low-nibble of the log PCM sample */
+    low_nibble = (absno >> segno)       /* right shift of mantissa and */
+      &(0x000F);                /* masking away leading '1' */
+    low_nibble = (0x000F) - low_nibble;
+
+    /* Joining the high-nibble and the low-nibble of the log PCM sample */
+    logbuf[n] = (high_nibble << 4) | low_nibble;
+
+    /* Add sign bit */
+    if (linbuf[n] >= 0)
+      logbuf[n] = logbuf[n] | (0x0080);
+  }
+}
+
+/* ................... End of ulaw_compress() ..................... */
+
+
+
+/* ................... Begin of ulaw_expand() ..................... */
+/*
+  ==========================================================================
+
+   FUNCTION NAME: ulaw_expand
+
+   DESCRIPTION: Mu law decoding rule according ITU-T Rec. G.711.
+
+   PROTOTYPE: void ulaw_expand(long lseg, short *logbuf, short *linbuf)
+
+   PARAMETERS:
+     lseg:	(In)  number of samples
+     logbuf:	(In)  buffer with compressed samples (8 bit right justified,
+                      without sign extension)
+     linbuf:	(Out) buffer with linear samples (14 bits left justified)
+
+   RETURN VALUE: none.
+
+   HISTORY:
+   10.Dec.91	1.0	Separated mu law expansion function
+
+  ============================================================================
+*/
+
+void ulaw_expand(long lseg, Byte *logbuf, short *linbuf)
+{
+  long n;                       /* aux.var. */
+  short segment;                /* segment (Table 2/G711, column 1) */
+  short mantissa;               /* low  nibble of log companded sample */
+  short exponent;               /* high nibble of log companded sample */
+  short sign;                   /* sign of output sample */
+  short step;
+
+  for (n = 0; n < lseg; n++) {
+    sign = logbuf[n] < (0x0080) /* sign-bit = 1 for positiv values */
+      ? -1 : 1;
+    mantissa = ~logbuf[n];      /* 1's complement of input value */
+    exponent = (mantissa >> 4) & (0x0007);      /* extract exponent */
+    segment = exponent + 1;     /* compute segment number */
+    mantissa = mantissa & (0x000F);     /* extract mantissa */
+
+    /* Compute Quantized Sample (14 bit left justified!) */
+    step = (4) << segment;      /* position of the LSB */
+    /* = 1 quantization step) */
+    linbuf[n] = sign *          /* sign */
+      (((0x0080) << exponent)   /* '1', preceding the mantissa */
+      +step * mantissa          /* left shift of mantissa */
+      + step / 2                /* 1/2 quantization step */
+      - 4 * 33);
+  }
+}
+
+/* ................... End of ulaw_expand() ..................... */

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