/*
=============================================================================

                          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".
       =============================================================
*/

/******************************************************************************
**
**  Filename:     g711_decoder.c
**
**  System:       RISC
**
**  Platform:     dsPIC33F
**
**  Description:  This file contains g711 Alaw and ulaw expand functions.
**
******************************************************************************/

#include "g711.h"
#include <stdio.h>

/******************************************************************************
**
**  FunctionName: alaw_expand ( )
**
**  Description:  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.
******************************************************************************/
void alaw_expand(long lseg, unsigned char* logbuf, short* linbuf)
{
  short         ix, mant, iexp;
  long          n;

  for (n = 0; n < lseg; n++)
  {
    //printf("Expanding: %2.2x ishigher127: %d", logbuf[n] & 0xFF, (logbuf[n]>127));
    ix = logbuf[n] ^ (0x0055);      //re-toggle toggled bits
    ix &= (0x007F);		            //remove sign bit
    iexp = ix >> 4;		            //extract exponent
    mant = ix & (0x000F);	        //now get mantissa

    //printf("iexp: %2.2x  mant: %2.2x ", iexp & 0xFF, mant & 0xFF);


    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;
   // printf(" linbuf: %4.4x mant: %4.4x -mant: %4.4x ", linbuf[n] & 0xFFFF, mant & 0xFFFF, (-mant) & 0xFFFF);
   // printf("\n");
  }
}
/* ................... End of alaw_expand() ..................... */

/* ................... Begin of ulaw_expand() ..................... */
/******************************************************************************
**
**  FunctionName: ulaw_expand ( )
**
**  Description:  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.
******************************************************************************/
void  ulaw_expand(long lseg, unsigned char* 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() ..................... */

/*-----------------------------------------------------------------------------
                      END OF FILE:  g711_decoder.c
-----------------------------------------------------------------------------*/


