text: /*************************************************************************/
  /*                                                                       */
  /*                  Language Technologies Institute                      */
  /*                     Carnegie Mellon University                        */
  /*                        Copyright (c) 2000                             */
  /*                        All Rights Reserved.                           */
  /*                                                                       */
  /*  Permission is hereby granted, free of charge, to use and distribute  */
  /*  this software and its documentation without restriction, including   */
  /*  without limitation the rights to use, copy, modify, merge, publish,  */
  /*  distribute, sublicense, and/or sell copies of this work, and to      */
  /*  permit persons to whom this work is furnished to do so, subject to   */
  /*  the following conditions:                                            */
  /*   1. The code must retain the above copyright notice, this list of    */
  /*      conditions and the following disclaimer.                         */
  /*   2. Any modifications must be clearly marked as such.                */
  /*   3. Original authors' names are not deleted.                         */
  /*   4. The authors' names are not used to endorse or promote products   */
  /*      derived from this software without specific prior written        */
  /*      permission.                                                      */
  /*                                                                       */
  /*  CARNEGIE MELLON UNIVERSITY AND THE CONTRIBUTORS TO THIS WORK         */
  /*  DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING      */
  /*  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT   */
  /*  SHALL CARNEGIE MELLON UNIVERSITY NOR THE CONTRIBUTORS BE LIABLE      */
  /*  FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES    */
  /*  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN   */
  /*  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,          */
  /*  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF       */
  /*  THIS SOFTWARE.                                                       */
  /*                                                                       */
  /*************************************************************************/
  /*             Author:  Alan W Black (awb@cs.cmu.edu)                    */
  /*               Date:  October 2000                                     */
  /*************************************************************************/
  /*                                                                       */
  /*  Convertion routines for various waveform encodings                   */
  /*                                                                       */
  /*  This contains software written external to Mimic                     */
  /*       ulaw code came via the Edinburgh Speech Tools                   */
  /*  g72x codec came from Sun Microsystems                                */
  /*                                                                       */
  /*************************************************************************/
  
  #include "g72x.h"
  
  /*
  ** This routine converts from linear to ulaw.
  **
  ** Craig Reese: IDA/Supercomputing Research Center
  ** Joe Campbell: Department of Defense
  ** 29 September 1989
  **
  ** References:
  ** 1) CCITT Recommendation G.711  (very difficult to follow)
  ** 2) "A New Digital Technique for Implementation of Any
  **     Continuous PCM Companding Law," Villeret, Michel,
  **     et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
  **     1973, pg. 11.12-11.17
  ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
  **     for Analog-to_Digital Conversion Techniques,"
  **     17 February 1987
  **
  ** Input: Signed 16 bit linear sample
  ** Output: 8 bit ulaw sample
  */
  
  #define ZEROTRAP                /* turn on the trap as per the MIL-STD */
  #define BIAS 0x84               /* define the add-in bias for 16 bit samples */
  #define CLIP 32635
  
  unsigned char cst_short_to_ulaw(short sample)
  {
      static const int exp_lut[256] =
          { 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
          4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
      };
      int sign, exponent, mantissa;
      unsigned char ulawbyte;
  
      /* Get the sample into sign-magnitude. */
      sign = (sample >> 8) & 0x80;        /* set aside the sign */
      if (sign != 0)
          sample = -sample;       /* get magnitude */
      if (sample > CLIP)
          sample = CLIP;          /* clip the magnitude */
  
      /* Convert from 16 bit linear to ulaw. */
      sample = sample + BIAS;
      exponent = exp_lut[(sample >> 7) & 0xFF];
      mantissa = (sample >> (exponent + 3)) & 0x0F;
      ulawbyte = ~(sign | (exponent << 4) | mantissa);
  #ifdef ZEROTRAP
      if (ulawbyte == 0)
          ulawbyte = 0x02;        /* optional CCITT trap */
  #endif
  
      return ulawbyte;
  }
  
  /*
  ** This routine converts from ulaw to 16 bit linear.
  **
  ** Craig Reese: IDA/Supercomputing Research Center
  ** 29 September 1989
  **
  ** References:
  ** 1) CCITT Recommendation G.711  (very difficult to follow)
  ** 2) MIL-STD-188-113,"Interoperability and Performance Standards
  **     for Analog-to_Digital Conversion Techniques,"
  **     17 February 1987
  **
  ** Input: 8 bit ulaw sample
  ** Output: signed 16 bit linear sample
  */
  
  short cst_ulaw_to_short(unsigned char ulawbyte)
  {
      static const int exp_lut[8] =
          { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
      int sign, exponent, mantissa;
      short sample;
  
      ulawbyte = ~ulawbyte;
      sign = (ulawbyte & 0x80);
      exponent = (ulawbyte >> 4) & 0x07;
      mantissa = ulawbyte & 0x0F;
      sample = exp_lut[exponent] + (mantissa << (exponent + 3));
      if (sign != 0)
          sample = -sample;
  
      return sample;
  }
  
  
  unsigned char *cst_g721_decode(int *actual_size, int size,
                                 const unsigned char *packed_residual)
  {
      struct g72x_state state;
      short sample_short;
      unsigned char *unpacked_residual;
      unsigned char code, xcode;
      int ur = 0;
      int dec_bits;
  
      *actual_size = size * 2;
      unpacked_residual = cst_alloc(unsigned char, *actual_size);
      g72x_init_state(&state);
      dec_bits = 4;               /* g721 4-bit encoding */
  
      for (ur = 0; ur < *actual_size; ur++)
      {
          xcode = packed_residual[ur / 2];
          if (ur % 2 == 0)
              code = (xcode & 0xF0) >> dec_bits;
          else
              code = (xcode & 0x0F);
          sample_short = g721_decoder(code, AUDIO_ENCODING_LINEAR, &state);
          unpacked_residual[ur] = cst_short_to_ulaw(sample_short);
      }
  
      return unpacked_residual;
  }
  
  unsigned char *cst_g721_encode(int *packed_size, int actual_size,
                                 const unsigned char *unpacked_residual)
  {
      struct g72x_state state;
      unsigned char *packed_residual;
      unsigned char code, xcode = 0;
      int ur = 0;
      int dec_bits;
  
      *packed_size = (actual_size + 1) / 2;       /* will round down to even number */
      packed_residual = cst_alloc(unsigned char, *packed_size);
  
      g72x_init_state(&state);
      dec_bits = 4;               /* g721 4-bit encoding */
  
      for (ur = 0; ur < actual_size; ur++)
      {
          code = g721_encoder((int) cst_ulaw_to_short(unpacked_residual[ur]),
                              AUDIO_ENCODING_LINEAR, &state);
          if (ur % 2 == 0)
          {
              xcode = 0;
              xcode = code << dec_bits;
          }
          else
          {
              xcode += code;
              packed_residual[ur / 2] = xcode;
          }
      }
  
      return packed_residual;
  
  }
  