diff intercom/g726/g726.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/g726.c	Fri Jun 25 09:57:52 2010 +0200
@@ -0,0 +1,3387 @@
+/*                                                           v2.0 24.Jan.2000
+=============================================================================
+
+                          U    U   GGG    SSSS  TTTTT
+                          U    U  G       S       T
+                          U    U  G  GG   SSSS    T
+                          U    U  G   G       S   T
+                           UUU     GG     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:         G726.C ADPCM AT 40, 32, 24, AND 16 KBIT/S MODULE
+
+ORIGINAL BY:
+   Jose' Sindi Yamamoto (Fortran version of the G.721)
+       <tdsindi@venus.cpqd.ansp.br>
+   Simao Ferraz de Campos Neto (C translation, adaptation&testing of the G.721)
+       <simao@venus.cpqd.ansp.br>
+   Fernando Tofolli Queiroz (Extension of the G.721 to the other rates=>G.726)
+       <tofolli@venus.cpqd.ansp.br>
+   Simao Ferraz de Campos Neto (Adaptation and testing of the G.726)
+       <simao@venus.cpqd.ansp.br>
+
+HISTORY:
+28.Feb.1994 v1.0c Version 1.0 in C, by translating Fortran to C (f2c)
+24.Jan.2000 v2.0  Corrected bug G726_compress() that caused incorrect 
+                  processing of test vector ri40fa. Corrected code
+                  provided by Jayesh Patel <jayesh@dspse.com>. 
+		  Verified by <simao.campos@labs.comsat.com>
+
+FUNCTIONS:
+Public:
+  G726_encode ..... G726 encoder function;
+
+  G726_decode ..... G726 decoder function;
+
+Private:
+  G726_accum ...... addition of predictor outputs to form the partial
+                    signal estimate (from the sixth order predictor) and
+                    the signal estimate.
+
+  G726_adda ....... addition of scale factor to logarithmic version of
+                    quantized difference signal.
+
+  G726_addb ....... addition of quantized difference signal and signal
+                    estimate to form reconstructed signal.
+
+  G726_addc....... obtain sign of addition of quantized difference signal
+                    and partial signal estimate.
+
+  G726_antilog .... convert quantized difference signal from the
+                    logarithmic to the linear domain.
+
+  G726_compress ... convert from uniform pcm to either a-law or u-law pcm.
+
+  G726_delaya ..... memory block.
+
+  G726_delayb ..... memory block.
+
+  G726_delayc ..... memory block.
+
+  G726_delayd ..... memory block.
+
+  G726_expand ..... convert either a-law (law=1) or u-law (law=0) to
+                    uniform pcm.
+
+  G726_filta ...... update of short term average of f(i).
+
+  G726_filtb ...... update of long term average of f(i).
+
+  G726_filtc ...... low pass filter of speed control parameter.
+
+  G726_filtd ...... update of fast quantizer scale factor.
+
+  G726_filte ...... update of slow quantizer scale factor.
+
+  G726_floata ..... convert 15-bit signed magnitude to floating point.
+
+  G726_floatb ..... convert 16-bit two's complement to floating point.
+
+  G726_fmult ...... multiply predictor coefficients with corresponding
+                    quantized difference signal or reconstructed signal.
+                    Multiplication is done in floating point format.
+
+  G726_functf ..... map quantizer output into the f(i) function.
+
+  G726_functw ..... map quantizer output into logarithmic version of scale
+                    factor multiplier.
+
+  G726_lima ....... limit speed control parameter.
+
+  G726_limb ....... limit quantizer scale factor.
+
+  G726_limc ....... limits on a2 coefficient of second order predictor.
+
+  G726_limd ....... limits on a1 coefficient of second order predictor.
+
+  G726_log ........ convert difference signal from linear to the
+                    logarithmic domain.
+
+  G726_mix ........ form linear combination of fast and slow quantizer
+                    scale factors.
+
+  G726_quan ....... quantize difference signal in logarithmic domain.
+
+  G726_reconst .... reconstruction of quantized difference signal in the
+                    logarithmic domain.
+
+  G726_subta ...... compute difference signal by subtracting signal
+                    estimate from input signal (or quantized reconstructed
+                    signal in decoder).
+
+  G726_subtb ...... scale logarithmic version of difference signal by
+                    subtracting scale factor.
+
+  G726_subtc ...... compute magnitude of the difference of short and
+                    long-term function of quantizer output sequence and
+                    then perform threshold comparison for quantizing speed
+                    control parameter.
+
+  G726_sync ....... re-encode output pcm sample in decoder for synchronous
+                    tandem coding.
+
+  G726_tone ....... partial band signal detection.
+
+  G726_trans ...... transition detector.
+
+  G726_triga ...... speed control trigger block.
+
+  G726_trigb ...... predictor trigger block.
+
+  G726_upa1 ....... update a1 coefficient of second order predictor.
+
+  G726_upa2 ....... update a2 coefficient of second order predictor.
+
+  G726_upb ........ update for coefficients of sixth order predictor.
+
+  G726_xor ........ one bit "exclusive or" of sign of difference  signal
+                    and sign of delayed difference signal.
+
+=============================================================================
+*/
+
+/*
+ *  .................. INCLUDES ..................
+ */
+#include "g726.h"
+
+
+/*
+ *  .................. FUNCTIONS ..................
+ */
+
+/*
+  ----------------------------------------------------------------------------
+
+        void G726_encode (short *inp_buf, short *out_buf, long smpno,
+        ~~~~~~~~~~~~~~~~  char *law, short rate, short r, G726_state *state);
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Simulation of the ITU-T G.726 ADPCM encoder. Takes the A or mu
+        law input array of shorts `inp_buf' (16 bit, right- justified,
+        without sign extension) of length `smpno', and saves the
+        encoded samples in the array of shorts `out_buf', with the
+        same number of samples and right-justified.
+
+        The state variables are saved in the structure `state', and the
+        reset can be stablished by making r equal to 1. The law is A if
+        `law'=='1', and mu law if `law'=='0'.
+
+	
+        Return value:
+        ~~~~~~~~~~~~~
+        None.
+
+        Prototype:      in file g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Version 1.0 in Fortran
+                        <tdsindi@venus.cpqd.ansp.br>
+        05.Feb.92 v1.0c Version 1.0 in C, by translating Fortran to C (f2c)
+                        <tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------------
+*/
+void G726_encode(inp_buf, out_buf, smpno, law, rate, r, state)
+unsigned char *inp_buf;
+short *out_buf;
+long smpno;
+char *law;
+short r;
+short rate;
+G726_state *state;
+{
+  short s;
+  short d, i;
+  short y;
+  short sigpk;
+  short sr, tr;
+  short yu;
+  short al, fi, dl, ap, dq, ds, se, ax, td, sl, wi;
+  short u1, u2, u3, u4, u5, u6;
+  short a1, a2, b1, b2, b3, b4, b5, b6;
+  short dqln;
+  short a1p, a2p, a1t, a2t, b1p, b2p, b3p, b4p, b5p, b6p, dq6, pk2,
+    sr2, wa1, wa2, wb1, wb2, wb3, wb4, wb5, wb6;
+  short dml, dln, app, dql, dms;
+  short dqs, tdp;
+  short sez;
+  short yut;
+  long yl;
+
+  long j;
+
+  /* Invert even bits if A law */
+  if (*law == '1') {
+    for (j = 0; j < smpno; j++)
+      inp_buf[j] ^= 85;
+  }
+
+  /* Process all desired samples in inp_buf to out_buf; The comments about
+   * general blocks are given as in G.726, and refer to: 4.1.1 Input PCM
+   * format conversion and difference signal computation    4.1.2 Adaptive
+   * quantizer 4.1.3 Inverse adaptive quantizer 4.1.4 Quantizer scale factor
+   * adaptation 4.1.5 Adaptation speed control 4.1.6 Adaptive predictor and
+   * reconstructed signal calculator 4.1.7 Tone and transition detector 4.1.8
+   * (Only in the decoder) */
+  for (j = 0; j < smpno; j++, r = 0) {
+    s = inp_buf[j];
+
+    /* Process `known-state' part of 4.2.6 */
+    G726_delayd(&r, &state->sr1, &sr2);
+    G726_delayd(&r, &state->sr0, &state->sr1);
+    G726_delaya(&r, &state->a2r, &a2);
+    G726_delaya(&r, &state->a1r, &a1);
+    G726_fmult(&a2, &sr2, &wa2);
+    G726_fmult(&a1, &state->sr1, &wa1);
+
+    G726_delayd(&r, &state->dq5, &dq6);
+    G726_delayd(&r, &state->dq4, &state->dq5);
+    G726_delayd(&r, &state->dq3, &state->dq4);
+    G726_delayd(&r, &state->dq2, &state->dq3);
+    G726_delayd(&r, &state->dq1, &state->dq2);
+    G726_delayd(&r, &state->dq0, &state->dq1);
+
+    G726_delaya(&r, &state->b1r, &b1);
+    G726_delaya(&r, &state->b2r, &b2);
+    G726_delaya(&r, &state->b3r, &b3);
+    G726_delaya(&r, &state->b4r, &b4);
+    G726_delaya(&r, &state->b5r, &b5);
+    G726_delaya(&r, &state->b6r, &b6);
+
+    G726_fmult(&b1, &state->dq1, &wb1);
+    G726_fmult(&b2, &state->dq2, &wb2);
+    G726_fmult(&b3, &state->dq3, &wb3);
+    G726_fmult(&b4, &state->dq4, &wb4);
+    G726_fmult(&b5, &state->dq5, &wb5);
+    G726_fmult(&b6, &dq6, &wb6);
+
+    G726_accum(&wa1, &wa2, &wb1, &wb2, &wb3, &wb4, &wb5, &wb6, &se,
+      &sez);
+
+    /* Process 4.2.1 */
+    G726_expand(&s, law, &sl);
+    G726_subta(&sl, &se, &d);
+
+    /* Process delays and `know-state' part of 4.2.5 */
+    G726_delaya(&r, &state->dmsp, &dms);
+    G726_delaya(&r, &state->dmlp, &dml);
+    G726_delaya(&r, &state->apr, &ap);
+    G726_lima(&ap, &al);
+
+    /* Process `know-state' parts of 4.2.4 */
+    G726_delayb(&r, &state->yup, &yu);
+    G726_delayc(&r, &state->ylp, &yl);
+    G726_mix(&al, &yu, &yl, &y);
+
+    /* Process 4.2.2 */
+    G726_log(&d, &dl, &ds);
+    G726_subtb(&dl, &y, &dln);
+    G726_quan(rate, &dln, &ds, &i);
+
+    /* Save ADPCM quantized sample into output buffer */
+    out_buf[j] = i;
+
+    /* Process 4.2.3 */
+    G726_reconst(rate, &i, &dqln, &dqs);
+    G726_adda(&dqln, &y, &dql);
+    G726_antilog(&dql, &dqs, &dq);
+
+    /* Part of 4.2.5 */
+    G726_functf(rate, &i, &fi);
+    G726_filta(&fi, &dms, &state->dmsp);
+    G726_filtb(&fi, &dml, &state->dmlp);
+
+    /* Remaining part of 4.2.4 */
+    G726_functw(rate, &i, &wi);
+    G726_filtd(&wi, &y, &yut);
+    G726_limb(&yut, &state->yup);
+    G726_filte(&state->yup, &yl, &state->ylp);
+
+    /* Process `known-state' part of 4.2.7 */
+    G726_delaya(&r, &state->tdr, &td);
+    G726_trans(&td, &yl, &dq, &tr);
+
+    /* More `known-state' parts of 4.2.6: update of `pk's */
+    G726_delaya(&r, &state->pk1, &pk2);
+    G726_delaya(&r, &state->pk0, &state->pk1);
+    G726_addc(&dq, &sez, &state->pk0, &sigpk);
+
+    /* 4.2.6: find sr0 */
+    G726_addb(&dq, &se, &sr);
+    G726_floatb(&sr, &state->sr0);
+
+    /* 4.2.6: find dq0 */
+    G726_floata(&dq, &state->dq0);
+
+    /* 4.2.6: prepar a2(r) */
+    G726_upa2(&state->pk0, &state->pk1, &pk2, &a2, &a1, &sigpk, &a2t);
+    G726_limc(&a2t, &a2p);
+    G726_trigb(&tr, &a2p, &state->a2r);
+
+    /* 4.2.6: prepar a1(r) */
+    G726_upa1(&state->pk0, &state->pk1, &a1, &sigpk, &a1t);
+    G726_limd(&a1t, &a2p, &a1p);
+    G726_trigb(&tr, &a1p, &state->a1r);
+
+    /* Remaining of 4.2.7 */
+    G726_tone(&a2p, &tdp);
+    G726_trigb(&tr, &tdp, &state->tdr);
+
+    /* Remaining of 4.2.5 */
+    G726_subtc(&state->dmsp, &state->dmlp, &tdp, &y, &ax);
+    G726_filtc(&ax, &ap, &app);
+    G726_triga(&tr, &app, &state->apr);
+
+    /* Remaining of 4.2.6: update of all `b's */
+    G726_xor(&state->dq1, &dq, &u1);    /* Here, b1 */
+    G726_upb(rate, &u1, &b1, &dq, &b1p);
+    G726_trigb(&tr, &b1p, &state->b1r);
+
+    G726_xor(&state->dq2, &dq, &u2);    /* Here, b2 */
+    G726_upb(rate, &u2, &b2, &dq, &b2p);
+    G726_trigb(&tr, &b2p, &state->b2r);
+
+    G726_xor(&state->dq3, &dq, &u3);    /* Here, b3 */
+    G726_upb(rate, &u3, &b3, &dq, &b3p);
+    G726_trigb(&tr, &b3p, &state->b3r);
+
+    G726_xor(&state->dq4, &dq, &u4);    /* Here, b4 */
+    G726_upb(rate, &u4, &b4, &dq, &b4p);
+    G726_trigb(&tr, &b4p, &state->b4r);
+
+    G726_xor(&state->dq5, &dq, &u5);    /* Here, b5 */
+    G726_upb(rate, &u5, &b5, &dq, &b5p);
+    G726_trigb(&tr, &b5p, &state->b5r);
+
+    G726_xor(&dq6, &dq, &u6);   /* At last, b6 */
+    G726_upb(rate, &u6, &b6, &dq, &b6p);
+    G726_trigb(&tr, &b6p, &state->b6r);
+  }
+}
+
+/* ........................ end of G726_encode() ....................... */
+
+
+/*
+  ----------------------------------------------------------------------------
+
+        void G726_decode (short *inp_buf, short *out_buf, long smpno,
+        ~~~~~~~~~~~~~~~~  char *law, short rate, short r, G726_state *state);
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Simulation of the ITU-T G.726 ADPCM decoder. Takes the ADPCM
+        input array of shorts `inp_buf' (16 bit, right- justified,
+        without sign extension) of length `smpno', and saves the
+        decoded samples (A or mu law) in the array of shorts
+        `out_buf', with the same number of samples and
+        right-justified.
+
+        The state variables are saved in the structure `state', and the
+        reset can be stablished by making r equal to 1. The law is A if
+        `law'=='1', and mu law if `law'=='0'.
+
+	
+        Return value:
+        ~~~~~~~~~~~~~
+        None.
+
+        Prototype:      in file g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Version 1.0 in Fortran
+                        <tdsindi@venus.cpqd.ansp.br>
+        05.Feb.92 v1.0c Version 1.0 in C, by translating Fortran to C (f2c)
+                        <tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------------
+*/
+void G726_decode(inp_buf, out_buf, smpno, law, rate, r, state)
+short *inp_buf;
+unsigned char *out_buf;
+long smpno;
+char *law;
+short r;
+short rate;
+G726_state *state;
+{
+  short i;
+  short y;
+  short sigpk;
+  short sr, tr;
+  short sp, dlnx, dsx, sd, slx, dlx, dx;        /* these are unique to
+                                                 * the decoder */
+  long yl;
+  short yu;
+  short al, fi, ap, dq, se, ax, td, wi;
+  short u1, u2, u3, u4, u5, u6;
+  short a1, a2, b1, b2, b3, b4, b5, b6;
+  short dqln;
+  short a1p, a2p, a1t, a2t, b1p, b2p, b3p, b4p, b5p, b6p, dq6, pk2,
+    sr2, wa1, wa2, wb1, wb2, wb3, wb4, wb5, wb6;
+  short dml, app, dql, dms;
+  short dqs, tdp;
+  short sez;
+  short yut;
+  long j;
+
+  /* Process all desired samples in inp_buf to out_buf; The comments about
+   * general blocks are given as in G.726, and refer to: 4.1.1 Input PCM
+   * format conversion and difference signal computation    4.1.2 Adaptive
+   * quantizer 4.1.3 Inverse adaptive quantizer 4.1.4 Quantizer scale factor
+   * adaptation 4.1.5 Adaptation speed control 4.1.6 Adaptive predictor and
+   * reconstructed signal calculator 4.1.7 Tone and transition detector 4.1.8
+   * Output PCM format conversion and synchronous coding adjustment */
+  for (j = 0; j < smpno; j++, r = 0) {
+    /* Process `known-state' part of 4.2.6 */
+    G726_delayd(&r, &state->sr1, &sr2);
+    G726_delayd(&r, &state->sr0, &state->sr1);
+    G726_delaya(&r, &state->a2r, &a2);
+    G726_delaya(&r, &state->a1r, &a1);
+    G726_fmult(&a2, &sr2, &wa2);
+    G726_fmult(&a1, &state->sr1, &wa1);
+
+    G726_delayd(&r, &state->dq5, &dq6);
+    G726_delayd(&r, &state->dq4, &state->dq5);
+    G726_delayd(&r, &state->dq3, &state->dq4);
+    G726_delayd(&r, &state->dq2, &state->dq3);
+    G726_delayd(&r, &state->dq1, &state->dq2);
+    G726_delayd(&r, &state->dq0, &state->dq1);
+
+    G726_delaya(&r, &state->b1r, &b1);
+    G726_delaya(&r, &state->b2r, &b2);
+    G726_delaya(&r, &state->b3r, &b3);
+    G726_delaya(&r, &state->b4r, &b4);
+    G726_delaya(&r, &state->b5r, &b5);
+    G726_delaya(&r, &state->b6r, &b6);
+
+    G726_fmult(&b1, &state->dq1, &wb1);
+    G726_fmult(&b2, &state->dq2, &wb2);
+    G726_fmult(&b3, &state->dq3, &wb3);
+    G726_fmult(&b4, &state->dq4, &wb4);
+    G726_fmult(&b5, &state->dq5, &wb5);
+    G726_fmult(&b6, &dq6, &wb6);
+
+    G726_accum(&wa1, &wa2, &wb1, &wb2, &wb3, &wb4, &wb5, &wb6, &se,
+      &sez);
+
+    /* Process delays and `know-state' part of 4.2.5 */
+    G726_delaya(&r, &state->dmsp, &dms);
+    G726_delaya(&r, &state->dmlp, &dml);
+    G726_delaya(&r, &state->apr, &ap);
+    G726_lima(&ap, &al);
+
+    /* Process `know-state' parts of 4.2.4 */
+    G726_delayb(&r, &state->yup, &yu);
+    G726_delayc(&r, &state->ylp, &yl);
+    G726_mix(&al, &yu, &yl, &y);
+
+    /* Retrieve ADPCM sample from input buffer */
+    i = inp_buf[j];
+
+    /* Process 4.2.3 */
+    G726_reconst(rate, &i, &dqln, &dqs);
+    G726_adda(&dqln, &y, &dql);
+    G726_antilog(&dql, &dqs, &dq);
+
+    /* Process `known-state' part of 4.2.7 */
+    G726_delaya(&r, &state->tdr, &td);
+    G726_trans(&td, &yl, &dq, &tr);
+
+    /* Part of 4.2.5 */
+    G726_functf(rate, &i, &fi);
+    G726_filta(&fi, &dms, &state->dmsp);
+    G726_filtb(&fi, &dml, &state->dmlp);
+
+    /* Remaining part of 4.2.4 */
+    G726_functw(rate, &i, &wi);
+    G726_filtd(&wi, &y, &yut);
+    G726_limb(&yut, &state->yup);
+    G726_filte(&state->yup, &yl, &state->ylp);
+
+    /* More `known-state' parts of 4.2.6: update of `pk's */
+    G726_delaya(&r, &state->pk1, &pk2);
+    G726_delaya(&r, &state->pk0, &state->pk1);
+    G726_addc(&dq, &sez, &state->pk0, &sigpk);
+
+    /* 4.2.6: find sr0 */
+    G726_addb(&dq, &se, &sr);
+    G726_floatb(&sr, &state->sr0);
+
+    /* 4.2.6: find dq0 */
+    G726_floata(&dq, &state->dq0);
+
+    /* Process 4.2.8 */
+    G726_compress(&sr, law, &sp);
+    G726_expand(&sp, law, &slx);
+    G726_subta(&slx, &se, &dx);
+    G726_log(&dx, &dlx, &dsx);
+    G726_subtb(&dlx, &y, &dlnx);
+    G726_sync(rate, &i, &sp, &dlnx, &dsx, law, &sd);
+
+    /* Save output PCM word in output buffer */
+    out_buf[j] = sd;
+
+    /* 4.2.6: prepar a2(r) */
+    G726_upa2(&state->pk0, &state->pk1, &pk2, &a2, &a1, &sigpk, &a2t);
+    G726_limc(&a2t, &a2p);
+    G726_trigb(&tr, &a2p, &state->a2r);
+
+    /* 4.2.6: prepar a1(r) */
+    G726_upa1(&state->pk0, &state->pk1, &a1, &sigpk, &a1t);
+    G726_limd(&a1t, &a2p, &a1p);
+    G726_trigb(&tr, &a1p, &state->a1r);
+
+    /* Remaining of 4.2.7 */
+    G726_tone(&a2p, &tdp);
+    G726_trigb(&tr, &tdp, &state->tdr);
+
+    /* Remaining of 4.2.5 */
+    G726_subtc(&state->dmsp, &state->dmlp, &tdp, &y, &ax);
+    G726_filtc(&ax, &ap, &app);
+    G726_triga(&tr, &app, &state->apr);
+
+    /* Remaining of 4.2.6: update of all `b's */
+    G726_xor(&state->dq1, &dq, &u1);    /* Here, b1 */
+    G726_upb(rate, &u1, &b1, &dq, &b1p);
+    G726_trigb(&tr, &b1p, &state->b1r);
+
+    G726_xor(&state->dq2, &dq, &u2);    /* Here, b2 */
+    G726_upb(rate, &u2, &b2, &dq, &b2p);
+    G726_trigb(&tr, &b2p, &state->b2r);
+
+    G726_xor(&state->dq3, &dq, &u3);    /* Here, b3 */
+    G726_upb(rate, &u3, &b3, &dq, &b3p);
+    G726_trigb(&tr, &b3p, &state->b3r);
+
+    G726_xor(&state->dq4, &dq, &u4);    /* Here, b4 */
+    G726_upb(rate, &u4, &b4, &dq, &b4p);
+    G726_trigb(&tr, &b4p, &state->b4r);
+
+    G726_xor(&state->dq5, &dq, &u5);    /* Here, b5 */
+    G726_upb(rate, &u5, &b5, &dq, &b5p);
+    G726_trigb(&tr, &b5p, &state->b5r);
+
+    G726_xor(&dq6, &dq, &u6);   /* At last, b6 */
+    G726_upb(rate, &u6, &b6, &dq, &b6p);
+    G726_trigb(&tr, &b6p, &state->b6r);
+  }
+
+  /* Invert even bits if A law */
+  if (*law == '1') {
+    for (j = 0; j < smpno; j++)
+      out_buf[j] ^= 85;
+  }
+
+}
+
+/* ...................... end of G726_decode() ...................... */
+
+
+/*
+  ----------------------------------------------------------------------
+
+        void G726_expand (short *s, char *law, short *sl);
+        ~~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Convert either a-law (law=1) or u-law (law=0)  to uniform pcm.
+
+ 	Inputs: s (sp in decoder), law
+ 	Output: sl (slx in decoder)
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_expand(s, law, sl)
+short *s;
+char *law;
+short *sl;
+{
+  long mant, iexp;
+  short s1, ss, sig, ssm, ssq, sss;
+
+  s1 = *s;
+
+  if (*law == '1') {
+    /* Invert sign bit */
+    s1 ^= 128;
+    if (s1 >= 128) {
+      s1 += -128;
+      sig = 4096;
+    } else {
+      sig = 0;
+
+    }
+    iexp = s1 / 16;
+
+    mant = s1 - (iexp << 4);
+    ss = (iexp == 0) ?
+      ((mant << 1) + 1 + sig) :
+      ((1 << (iexp - 1)) * ((mant << 1) + 33) + sig);
+
+    sss = ss / 4096;
+    ssm = ss & 4095;
+    ssq = ssm << 1;
+  } else {
+    /* Invert sign bit */
+    s1 ^= 128;
+    if (s1 >= 128) {
+      s1 += -128;
+      s1 ^= 127;
+      sig = 8192;
+    } else {
+      sig = 0;
+      s1 ^= 127;
+    }
+    iexp = s1 / 16;
+
+    mant = s1 - (iexp << 4);
+
+    ss = (iexp == 0) ?
+      ((mant << 1) + sig) :
+      ((1 << iexp) * ((mant << 1) + 33) - 33 + sig);
+
+    sss = ss / 8192;
+    ssq = ss & 8191;
+  }
+
+  *sl = (sss == 0) ? ssq : ((16384 - ssq) & 16383);
+
+}
+
+/* ...................... end of G726_expand() ...................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_subta (short *sl, short *se, short *d);
+        ~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Compute difference signal by subtracting  signal estimate from
+        input signal (or  quantized reconstructed signal in decoder).
+
+ 	Inputs: sl (slx in decoder), se
+ 	Output: d  (dx in decoder)
+
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+
+ ----------------------------------------------------------------------
+*/
+void G726_subta(sl, se, d)
+short *sl, *se, *d;
+{
+  long se1;
+  long sl1, sei, sli;
+  short ses, sls;
+
+  sls = (*sl >> 13);
+
+  sl1 = *sl;
+  se1 = *se;
+
+  /* Sign extension */
+  sli = (sls == 0) ? sl1 : (sl1 + 49152);
+
+  ses = (*se >> 14);
+
+  /* Sign extension */
+  sei = (ses == 0) ? se1 : (se1 + 32768);
+
+  /* 16 bit TC */
+  *d = (short) ((sli + 65536 - sei) & 65535);
+
+}
+
+/* ......................... end of G726_subta() ......................... */
+
+
+/*
+  --------------------------------------------------------------------------
+
+        void G726_log (short *d, short *dl, short *ds);
+        ~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Convert difference signal from linear to the logarithmic domain.
+
+        Prototype: in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f 1st release to UGST, in Fortran.
+                        <tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c release of 1st version, in C.
+ 	                <tdsimao@venus.cpqd.ansp.br>
+
+  --------------------------------------------------------------------------
+*/
+void G726_log(d, dl, ds)
+short *d, *dl, *ds;
+{
+  long mant;
+  long d1;
+  long dqm, exp_;
+
+  *ds = (*d >> 15);
+
+  d1 = *d;
+
+  /* Convert from 2-complement to signed magnitude */
+  dqm = (*ds) ? ((65536 - d1) & 32767) : d1;
+
+  /* Compute exponent */
+  if (dqm >= 16384)
+    exp_ = 14;
+  else if (dqm >= 8192)
+    exp_ = 13;
+  else if (dqm >= 4096)
+    exp_ = 12;
+  else if (dqm >= 2048)
+    exp_ = 11;
+  else if (dqm >= 1024)
+    exp_ = 10;
+  else if (dqm >= 512)
+    exp_ = 9;
+  else if (dqm >= 256)
+    exp_ = 8;
+  else if (dqm >= 128)
+    exp_ = 7;
+  else if (dqm >= 64)
+    exp_ = 6;
+  else if (dqm >= 32)
+    exp_ = 5;
+  else if (dqm >= 16)
+    exp_ = 4;
+  else if (dqm >= 8)
+    exp_ = 3;
+  else if (dqm >= 4)
+    exp_ = 2;
+  else if (dqm >= 2)
+    exp_ = 1;
+  else
+    exp_ = 0;
+
+  /* Compute approximation log2(1+x) = x */
+  mant = ((dqm << 7) >> exp_) & 127;
+
+  /* Combine mantissa and exponent (7 and 4) bits into a 11-bit word */
+  *dl = (short) ((exp_ << 7) + mant);
+
+}
+
+/* ........................ end of G726_log() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_quan (short rate, short *dln, short *ds, short *i);
+        ~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Quantize difference signal in logarithmic
+ 	domain.
+
+ 	Inputs: dln, ds, rate
+ 	Output: i
+
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_quan(rate, dln, ds, i)
+short *dln, *ds, *i;
+short rate;
+{
+  if (rate == 4) {
+    if (*dln >= 3972)
+      *i = 1;
+    else if (*dln >= 2048)
+      *i = 15;
+    else if (*dln >= 400)
+      *i = 7;
+    else if (*dln >= 349)
+      *i = 6;
+    else if (*dln >= 300)
+      *i = 5;
+    else if (*dln >= 246)
+      *i = 4;
+    else if (*dln >= 178)
+      *i = 3;
+    else if (*dln >= 80)
+      *i = 2;
+    else
+      *i = 1;
+
+    /* Adjust for sign */
+    if (*ds)
+      *i = 15 - *i;
+
+    if (*i == 0)
+      *i = 15;
+  }
+
+  /* ......... end of 32 kbit part ........... */
+  else if (rate == 3) {
+    if (*dln >= 2048)
+      *i = 7;
+    else if (*dln >= 331)
+      *i = 3;
+    else if (*dln >= 218)
+      *i = 2;
+    else if (*dln >= 8)
+      *i = 1;
+    else if (*dln >= 0)
+      *i = 7;
+
+    /* Adjust for sign */
+    if (*ds)
+      *i = 7 - *i;
+
+    if (*i == 0)
+      *i = 7;
+  }
+  /* ......... end of 24 kbit part ........... */
+  else if (rate == 2) {
+    if (*dln >= 2048)
+      *i = 0;
+    else if (*dln >= 261)
+      *i = 1;
+    else
+      *i = 0;
+
+    /* Adjust for sign */
+    if (*ds)
+      *i = 3 - *i;
+  }
+  /* ......... end of 16 kbit part ........... */
+  else {
+    if (*dln >= 4080)
+      *i = 2;
+    else if (*dln >= 3974)
+      *i = 1;
+    else if (*dln >= 2048)
+      *i = 31;
+    else if (*dln >= 553)
+      *i = 15;
+    else if (*dln >= 528)
+      *i = 14;
+    else if (*dln >= 502)
+      *i = 13;
+    else if (*dln >= 475)
+      *i = 12;
+    else if (*dln >= 445)
+      *i = 11;
+    else if (*dln >= 413)
+      *i = 10;
+    else if (*dln >= 378)
+      *i = 9;
+    else if (*dln >= 339)
+      *i = 8;
+    else if (*dln >= 298)
+      *i = 7;
+    else if (*dln >= 250)
+      *i = 6;
+    else if (*dln >= 198)
+      *i = 5;
+    else if (*dln >= 139)
+      *i = 4;
+    else if (*dln >= 68)
+      *i = 3;
+    else if (*dln >= 0)
+      *i = 2;
+
+    if (*ds)
+      *i = 31 - *i;
+
+    if (*i == 0)
+      *i = 31;
+
+  }                             /* ......... end of 40 kbit part ........... */
+
+}
+
+/* ........................ end of G726_quan() ........................ */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_subtb (short *dl, short *y, short *dln);
+        ~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Scale logarithmic version of difference signal  by subtracting
+        scale factor.
+
+ 	Inputs:   dl (dlx no decodificador), y
+ 	Output:   dln (dlnx no decodificador)
+
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_subtb(dl, y, dln)
+short *dl, *y, *dln;
+{
+  *dln = (*dl + 4096 - (*y >> 2)) & 4095;
+
+}
+
+/* ........................ end of G726_subtb() ........................ */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_adda (short *dqln, short *y, short *dql);
+        ~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Addition of scale factor to logarithmic  version of quantized
+        difference signal.
+
+ 	Inputs: dqln, y
+ 	Output: dql
+
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_adda(dqln, y, dql)
+short *dqln, *y, *dql;
+{
+  *dql = (*dqln + (*y >> 2)) & 4095;
+
+}
+
+/* ....................... end of G726_adda() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_antilog (short *dql, short *dqs, short *dq);
+        ~~~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Convert quantized difference signal from the  logarithmic to
+        the linear domain.
+
+ 	Inputs:   dql, dqs
+ 	Output:   dq
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_antilog(dql, dqs, dq)
+short *dql, *dqs, *dq;
+{
+  long dqmag;
+  long ds, dmn, dex, dqt;
+
+  /* Extract 4-bit exponent */
+  ds = (*dql >> 11);
+  dex = (*dql >> 7) & 15;
+
+  /* Extract 7-bit mantissa */
+  dmn = *dql & 127;
+
+  dqt = dmn + 128;
+
+  /* Convert mantissa to linear using the approx. 2**x = 1+x */
+  dqmag = ds ? 0 : ((dqt << 7) >> (14 - dex));
+
+  /* Attach sign bit to signed mag. word */
+  *dq = (short) (*dqs << 15) + dqmag;
+}
+
+/* ..................... end of G726_antilog() ..................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_reconst (short rate, short *i, short *dqln, short *dqs);
+        ~~~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Reconstruction of quantized difference signal  in the
+        logarithmic domain.
+
+ 	Inputs:   i, rate
+ 	Outputs:  dqln, dqs
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_reconst(rate, i, dqln, dqs)
+short *i, *dqln, *dqs;
+short rate;
+{
+  if (rate == 4) {
+    /* Initialized data */
+    static short tab[16] = { 2048, 4, 135, 213, 273, 323, 373, 425,
+      425, 373, 323, 273, 213, 135, 4, 2048
+    };
+
+    /* Extract sign */
+    *dqs = (*i >> 3);
+
+    /* Table look-up */
+    *dqln = tab[*i];
+  }
+  /* ............... end of 32 kbit part
+   * ................. */
+  else if (rate == 3) {
+    /* Initialized data */
+    static short tab[8] = { 2048, 135, 273, 373, 373, 273, 135, 2048 };
+
+    *dqs = (*i >> 2);
+
+    /* Table look-up */
+    *dqln = tab[*i];
+
+  }
+
+  /* ............... end of 24 kbit part
+   * ................. */
+  else if (rate == 2) {
+    /* Initialized data */
+    static short tab[4] = { 116, 365, 365, 116 };
+
+    *dqs = (*i >> 1);
+
+    /* Table look-up */
+    *dqln = tab[*i];
+
+  }                             /* ............... end of 16 kbit part
+                                 * ................. */
+  else {
+    /* Initialized data */
+    static short tab[32] =
+      { 2048, 4030, 28, 104, 169, 224, 274, 318, 358, 395, 429,
+      459, 488, 514, 539, 566, 566, 539, 514, 488, 459, 429, 395, 358,
+        318, 274, 224,
+      169, 104, 28, 4030, 2048
+    };
+
+    *dqs = (*i >> 4);
+
+    /* Table look-up */
+    *dqln = tab[*i];
+
+  }                             /* ................ end of 40 kbit part
+                                 * ................... */
+
+
+}
+
+/* ....................... end of G726_reconst() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_delaya (short *r, short *x, short *y);
+        ~~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Memory block.
+
+ 	Inputs:    r, x
+ 	Output:    y
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_delaya(r, x, y)
+short *r, *x, *y;
+{
+  *y = (*r == 0) ? *x : 0;
+
+}
+
+/* ....................... end of G726_delaya() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_delayb (short *r, short *x, short *y);
+        ~~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Memory block.
+
+ 	Inputs:    r, x
+ 	Output:    y
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_delayb(r, x, y)
+short *r, *x, *y;
+{
+  *y = (*r == 0) ? *x : 544;
+
+}
+
+/* ....................... end of G726_delayb() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_delayc (short *r, long *x, long *y);
+        ~~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Memory block.
+
+ 	Inputs:    r, x
+ 	Output:    y
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_delayc(r, x, y)
+short *r;
+long *x, *y;
+{
+  *y = (*r == 0) ? *x : 34816;
+
+}
+
+/* ....................... end of G726_delayc() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_delayd (short *r, short *x, short *y);
+        ~~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Memory block
+
+ 	Inputs:   r, x
+ 	Output:   y
+
+        Return value:          none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_delayd(r, x, y)
+short *r, *x, *y;
+{
+  *y = (*r == 0) ? *x : 32;
+
+}
+
+/* ....................... end of G726_delayd() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_filtd (short *wi, short *y, short *yut);
+        ~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Update of fast quantizer scale factor.
+
+ 	Inputs: wi, y
+ 	Output: yut
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_filtd(wi, y, yut)
+short *wi, *y, *yut;
+{
+  long difs, difsx;
+  long y1;
+  long wi1, dif;
+
+  /* Compute difference */
+  wi1 = *wi;
+  y1 = *y;
+  dif = ((wi1 << 5) + 131072 - y1) & 131071;
+  difs = (dif >> 16);
+
+  /* Time constant is 1/32; sign extension */
+  difsx = (difs == 0) ? (dif >> 5) : ((dif >> 5) + 4096);
+
+  *yut = (short) ((y1 + difsx) & 8191);
+
+}
+
+/* ....................... end of G726_filte() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_filte (short *yup, long *yl, long *ylp);
+        ~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Update of slow quantizer scale factor.
+
+
+ 	Inputs:  yup, yl
+ 	Output:  ylp
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_filte(yup, yl, ylp)
+short *yup;
+long *yl, *ylp;
+{
+  long difs, difsx;
+  long dif, dif1, yup1;
+
+  /* Compute difference */
+  yup1 = *yup;
+  dif1 = 1048576 - *yl;
+  dif = (yup1 + (dif1 >> 6)) & 16383;
+  difs = (dif >> 13);
+
+  /* Sign extension */
+  difsx = (difs == 0) ? dif : (dif + 507904);
+
+  *ylp = (*yl + difsx) & 524287;
+
+}
+
+/* ....................... end of G726_filte() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_functw (short rate, short *i, short *wi);
+        ~~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Map quantizer output into logarithmic version  of scale factor
+        multiplier.
+
+ 	Inputs: i, rate
+ 	Output: wi
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_functw(rate, i, wi)
+short *i, *wi;
+short rate;
+{
+  if (rate == 4) {
+    /* Initialized data */
+    static short tab[8] = { 4084, 18, 41, 64, 112, 198, 355, 1122 };
+    short im, is;
+
+    is = (*i >> 3);
+
+    im = (is == 0) ? (*i & 7) : ((15 - *i) & 7);
+
+    /* Scale factor multiplier */
+    *wi = tab[im];
+
+
+  }
+
+
+
+
+  /* ................. end of 32 kbit part
+   * .............. */
+  else if (rate == 3) {
+
+    /* Initialized data */
+    static short tab[4] = { 4092, 30, 137, 582 };
+    short im, is;
+
+
+    is = (*i >> 2);
+
+    im = (is == 0) ? (*i & 3) : ((7 - *i) & 3);
+
+    *wi = tab[im];
+
+
+
+  }
+
+
+
+
+  /* ................. end of 24 kbit part
+   * .............. */
+  else if (rate == 2) {
+    /* Initialized data */
+    static short tab[2] = { 4074, 439 };
+    short im, is;
+
+
+    is = (*i >> 1);
+
+    im = (is == 0) ? (*i & 1) : ((3 - *i) & 1);
+
+    *wi = tab[im];
+
+  }
+
+
+
+
+  /* ................. end of 16 kbit part
+   * .............. */
+  else {
+    /* Initialized data */
+    static short tab[16] =
+      { 14, 14, 24, 39, 40, 41, 58, 100, 141, 179, 219, 280, 358,
+      440, 529, 696
+    };
+    short im, is;
+
+    is = (*i >> 4);
+
+    im = (is == 0) ? (*i & 15) : ((31 - *i) & 15);
+
+    *wi = tab[im];
+  }                             /* ................. end of 40 kbit part
+                                 * .............. */
+}
+
+/* ....................... end of G726_functw() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_limb (short *yut, short *yup);
+        ~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Limit quantizer scale factor.
+
+ 	Inputs: yut
+ 	Output: yup
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_limb(yut, yup)
+short *yut, *yup;
+{
+  short gell, geul;
+
+  geul = ((*yut + 11264) & 16383) >> 13;
+  gell = ((*yut + 15840) & 16383) >> 13;
+
+  if (gell == 1)
+    *yup = 544;                 /* Lower limit is 1.06 */
+  else if (geul == 0)
+    *yup = 5120;                /* Upper limit is 10.0 */
+  else
+    *yup = *yut;
+
+}
+
+/* ....................... end of G726_limb() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_mix (short *al, short *yu, long *yl, short *y);
+        ~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Form linear combination of fast and slow  quantizer scale
+        factors.
+
+ 	Inputs:    al, yu, yl
+ 	Output:    y
+
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_mix(al, yu, yl, y)
+short *al, *yu;
+long *yl;
+short *y;
+{
+  long difm, difs, prod;
+  long prodm, al1;
+  long yu1, dif;
+
+  /* Preamble */
+  al1 = *al;
+  yu1 = *yu;
+
+  /* Compute difference */
+  dif = (yu1 + 16384 - (*yl >> 6)) & 16383;
+  difs = (dif >> 13);
+
+  /* Compute magnitude of difference */
+  difm = (difs == 0) ? dif : ((16384 - dif) & 8191);
+
+  /* Compute magnitude of product */
+  prodm = ((difm * al1) >> 6);
+
+  /* Convert magnitude to two's complement */
+  prod = (difs == 0) ? prodm : ((16384 - prodm) & 16383);
+
+  *y = (short) (((*yl >> 6) + prod) & 8191);
+
+}
+
+/* ....................... end of G726_mix() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_filta (short *fi, short *dms, short *dmsp);
+        ~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Update of short term average of f(i).
+
+ 	Inputs:   fi, dms
+ 	Output:   dmsp
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_filta(fi, dms, dmsp)
+short *fi, *dms, *dmsp;
+{
+  short difs, difsx;
+  short dif;
+
+  /* Compute difference */
+  dif = ((*fi << 9) + 8192 - *dms) & 8191;
+  difs = (dif >> 12);
+
+  /* Time constant is 1/32, sign extension */
+  difsx = (difs == 0) ? (dif >> 5) : ((dif >> 5) + 3840);
+
+  *dmsp = (difsx + *dms) & 4095;
+
+}
+
+/* ....................... end of G726_filta() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_filtb (short *fi, short *dml, short *dmlp);
+        ~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Update of long term average of f(i).
+
+ 	Inputs:    fi, dml
+ 	Output:    dmlp
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_filtb(fi, dml, dmlp)
+short *fi, *dml, *dmlp;
+{
+  long difs, difsx;
+  long fi1;
+  long dif, dml1;
+
+  /* Preamble */
+  fi1 = *fi;
+  dml1 = *dml;
+
+  /* Compute difference */
+  dif = ((fi1 << 11) + 32768 - dml1) & 32767;
+  difs = (dif >> 14);
+
+  /* Time constant is 1/28, sign extension */
+  difsx = (difs == 0) ? (dif >> 7) : ((dif >> 7) + 16128);
+
+  *dmlp = (short) ((difsx + dml1) & 16383);
+
+}
+
+/* ....................... end of G726_filtb() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_filtc (short *ax, short *ap, short *app);
+        ~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Low pass filter of speed control parameter.
+
+ 	Inputs:   ax, ap
+ 	Output:   app
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_filtc(ax, ap, app)
+short *ax, *ap, *app;
+{
+  short difs, difsx;
+  short dif;
+
+  /* Compute difference */
+  dif = ((*ax << 9) + 2048 - *ap) & 2047;
+  difs = (dif >> 10);
+
+  /* Time constant is 1/16, sign extension */
+  difsx = (difs == 0) ? (dif >> 4) : ((dif >> 4) + 896);
+
+  *app = (difsx + *ap) & 1023;
+
+}
+
+/* .................... end of G726_filtc() .................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_functf (short rate, short *i, short *fi);
+        ~~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Map quantizer output into the f(i) function.
+
+ 	Inputs:   i, rate
+ 	Output:   fi
+
+        Return value:          none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_functf(rate, i, fi)
+short *i, *fi;
+short rate;
+
+{
+  short im, is;
+
+  if (rate == 4) {
+    /* Initialized data */
+    static short tab[8] = { 0, 0, 0, 1, 1, 1, 3, 7 };
+
+    is = (*i >> 3);
+
+    im = (is == 0) ? (*i & 7) : ((15 - *i) & 7);
+
+    *fi = tab[im];
+  }
+  /* ................ end of 32 kbit part
+   * ................. */
+  else if (rate == 3) {
+    /* Initialized data */
+    static short tab[4] = { 0, 1, 2, 7 };
+
+    is = (*i >> 2);
+
+    im = (is == 0) ? (*i & 3) : ((7 - *i) & 3);
+
+    *fi = tab[im];
+
+  }                             /* ................ end of 24 kbit part
+                                 * ................. */
+  else if (rate == 2) {
+    /* Initialized data */
+    static short tab[2] = { 0, 7 };
+
+
+    is = (*i >> 1);
+
+    im = (is == 0) ? (*i & 1) : ((3 - *i) & 1);
+
+    *fi = tab[im];
+
+  }
+  /* ................ end of 16 kbit part
+   * ................. */
+  else {
+    /* Initialized data */
+    static short tab[16] =
+      { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 6 };
+
+
+    is = (*i >> 4);
+
+    im = (is == 0) ? (*i & 15) : ((31 - *i) & 15);
+
+    *fi = tab[im];
+
+  }                             /* ................ end of 40 kbit part
+                                 * ................. */
+}
+
+/* ...................... end of G726_functf() ...................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_lima (short *ap, short *al);
+        ~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Limit speed control parameter.
+
+ 	Inputs:   ap
+ 	Output:   al
+
+        Return value:          none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_lima(ap, al)
+short *ap, *al;
+{
+  *al = (*ap >= 256) ? 64 : (*ap >> 2);
+
+}
+
+/* ....................... end of G726_lima() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_subtc (short *dmsp, short *dmlp, short *tdp,
+        ~~~~~~~~~~~~~~~  short *y, short *ax);
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Functions of quantizer output sequence  and then perform
+        threshold comparison for  quantizing speed control parameter.
+        compute magnitude of the difference of short and  long-term
+
+ 	Inputs:   dmsp, dmlp, tdp, y
+ 	Output:   ax
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_subtc(dmsp, dmlp, tdp, y, ax)
+short *dmsp, *dmlp, *tdp, *y, *ax;
+{
+  long difm, difs, dthr, dmlp1, dmsp1;
+  long dif;
+
+  /* Preamble */
+  dmsp1 = *dmsp;
+  dmlp1 = *dmlp;
+
+  /* Compute difference */
+  dif = ((dmsp1 << 2) + 32768 - dmlp1) & 32767;
+  difs = (dif >> 14);
+
+  /* Compute magnitude of difference */
+  difm = (difs == 0) ? dif : ((32768 - dif) & 16383);
+
+  /* Compute threshold */
+  dthr = (dmlp1 >> 3);
+
+  /* Quantize speed control parameter */
+  *ax = (*y >= 1536 && difm < dthr && *tdp == 0) ? 0 : 1;
+
+}
+
+/* ....................... end of G726_subtc() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_triga (short *tr, short *app, short *apr);
+        ~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Speed control trigger block.
+
+ 	Inputs: tr, app
+ 	Output: apr
+
+        Return value:          none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_triga(tr, app, apr)
+short *tr, *app, *apr;
+{
+  *apr = (*tr == 0) ? (*app) : 256;
+
+}
+
+/* ....................... end of G726_triga() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_accum (short *wa1, short *wa2, short *wb1,
+        ~~~~~~~~~~~~~~~  short *wb2, short *wb3, short *wb4,
+                        short *wb5, short *wb6, short *se, short *sez);
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Addition of predictor outputs to form the partial  signal
+        estimate (from the sixth order predictor)  and the signal
+        estimate.
+
+ 	Inputs:   wa1, wa2, wb1, wb2, wb3, wb4, wb5, wb6
+ 	Output:   se, sez
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_accum(wa1, wa2, wb1, wb2, wb3, wb4, wb5, wb6, se, sez)
+short *wa1, *wa2, *wb1, *wb2, *wb3, *wb4, *wb5, *wb6, *se, *sez;
+{
+  unsigned long sezi;
+  unsigned long wa11, wa21, wb11, wb21, wb31, wb41, wb51, wb61, sei;
+
+  /* Preamble */
+  wa11 = *wa1;
+  wa21 = *wa2;
+  wb11 = *wb1;
+  wb21 = *wb2;
+  wb31 = *wb3;
+  wb41 = *wb4;
+  wb51 = *wb5;
+  wb61 = *wb6;
+
+  /* Sum of partial signal estimate */
+  sezi = (((((((((wb11 + wb21) & 65535) + wb31) & 65535)
+            + wb41) & 65535) + wb51) & 65535) + wb61) & 65535;
+
+  /* Complete sum for signal estimate */
+  sei = (((sezi + wa21) & 65535) + wa11) & 65535;
+
+  *sez = (short) (sezi >> 1);
+  *se = (short) (sei >> 1);
+
+}
+
+/* ....................... end of G726_accum() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_addb (short *dq, short *se, short *sr);
+        ~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Addition of quantized difference signal and  signal estimate
+        to form reconstructed signal.
+
+ 	Inputs:   dq, se
+ 	Output:   sr
+
+        Return value:          none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+  ----------------------------------------------------------------------
+*/
+void G726_addb(dq, se, sr)
+short *dq, *se, *sr;
+{
+  unsigned long dq1, se1;
+  unsigned long dqi, sei;
+  short dqs, ses;
+
+  /* Preamble */
+  dq1 = *dq & 65535;
+  se1 = *se;
+
+  /* Sign */
+  dqs = (*dq >> 15) & 1;
+
+  /* Convert signed magnitude to 2's complement */
+  dqi = (dqs == 0) ? dq1 : ((65536 - (dq1 & 32767)) & 65535);
+
+  ses = (*se >> 14);
+
+  /* Sign extension */
+  sei = (ses == 0) ? se1 : ((1 << 15) + se1);
+
+  *sr = (short) ((dqi + sei) & 65535);
+
+}
+
+/* ....................... end of G726_addb() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_addc (short *dq, short *sez, short *pk0,
+        ~~~~~~~~~~~~~~  short *sigpk);
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Obtain sign of addition of quantized difference  signal and
+        partial signal estimate.
+
+ 	Inputs:   dq, sez
+ 	Outputs:   pk0, sigpk
+
+        Return value:          none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_addc(dq, sez, pk0, sigpk)
+short *dq, *sez, *pk0, *sigpk;
+{
+  unsigned long sezi;
+  short sezs;
+  unsigned long dqsez, dq1;
+  unsigned long dqi;
+  short dqs;
+  unsigned long sez1;
+
+  /* Preamble */
+  dq1 = *dq & 65535;
+  sez1 = *sez;
+
+  /* Get sign */
+  dqs = (*dq >> 15) & 1;
+
+  /* Convert signed magnitude to 2's compelemnent */
+  dqi = (dqs == 0) ? dq1 : ((65536 - (dq1 & 32767)) & 65535);
+
+  sezs = (*sez >> 14);
+
+  /* Sign extension */
+  sezi = (sezs == 0) ? sez1 : (sez1 + 32768);
+
+  dqsez = (dqi + sezi) & 65535;
+
+  *pk0 = (short) (dqsez >> 15);
+  *sigpk = (dqsez == 0) ? 1 : 0;
+
+}
+
+/* ....................... end of G726_addc() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_floata (short *dq, short *dq0);
+        ~~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Convert 16-bit signed magnitude to floating  point.
+
+ 	Inputs:  dq
+ 	Output:  dq0
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_floata(dq, dq0)
+short *dq, *dq0;
+{
+  long mant;
+  long mag, exp_;
+  long dqs;
+
+  dqs = (*dq >> 15) & 1;
+
+  /* Compute magnitude */
+  mag = *dq & 32767;
+
+  /* Exponent */
+  if (mag >= 16384)
+    exp_ = 15;
+  else if (mag >= 8192)
+    exp_ = 14;
+  else if (mag >= 4096)
+    exp_ = 13;
+  else if (mag >= 2048)
+    exp_ = 12;
+  else if (mag >= 1024)
+    exp_ = 11;
+  else if (mag >= 512)
+    exp_ = 10;
+  else if (mag >= 256)
+    exp_ = 9;
+  else if (mag >= 128)
+    exp_ = 8;
+  else if (mag >= 64)
+    exp_ = 7;
+  else if (mag >= 32)
+    exp_ = 6;
+  else if (mag >= 16)
+    exp_ = 5;
+  else if (mag >= 8)
+    exp_ = 4;
+  else if (mag >= 4)
+    exp_ = 3;
+  else if (mag >= 2)
+    exp_ = 2;
+  else if (mag == 1)
+    exp_ = 1;
+  else
+    exp_ = 0;
+
+  /* Compute mantissa w/a 1 in the most sig. bit */
+  mant = (mag == 0) ? (1 << 5) : ((mag << 6) >> exp_);
+  /* Combine sign, exponent and mantissa (1,4,6) bits in a word */
+  *dq0 = (short) ((dqs << 10) + (exp_ << 6) + mant);
+
+}
+
+/* ....................... end of G726_floata() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_floatb (short *sr, short *sr0);
+        ~~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Convert 16-bit two's complement to floating point.
+
+ 	Inputs:   sr
+ 	Output:   sr0
+
+        Return value:          none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_floatb(sr, sr0)
+short *sr, *sr0;
+{
+  long mant;
+  long mag, exp_, srr, srs;
+
+  /* Preamble */
+  srr = *sr & 65535;
+
+  /* Sign */
+  srs = (srr >> 15);
+
+  /* Compute magnitude */
+  mag = (srs == 0) ? srr : ((65536 - srr) & 32767);
+
+  /* Exponent */
+  if (mag >= 16384)
+    exp_ = 15;
+  else if (mag >= 8192)
+    exp_ = 14;
+  else if (mag >= 4096)
+    exp_ = 13;
+  else if (mag >= 2048)
+    exp_ = 12;
+  else if (mag >= 1024)
+    exp_ = 11;
+  else if (mag >= 512)
+    exp_ = 10;
+  else if (mag >= 256)
+    exp_ = 9;
+  else if (mag >= 128)
+    exp_ = 8;
+  else if (mag >= 64)
+    exp_ = 7;
+  else if (mag >= 32)
+    exp_ = 6;
+  else if (mag >= 16)
+    exp_ = 5;
+  else if (mag >= 8)
+    exp_ = 4;
+  else if (mag >= 4)
+    exp_ = 3;
+  else if (mag >= 2)
+    exp_ = 2;
+  else if (mag == 1)
+    exp_ = 1;
+  else
+    exp_ = 0;
+
+  /* Compute mantissa w/a 1 in the most sig. bit */
+  mant = (mag == 0) ? (1 << 5) : ((mag << 6) >> exp_);
+
+  /* Combine sign, exponent and mantissa (1,4,6) bits in a word */
+  *sr0 = (short) ((srs << 10) + (exp_ << 6) + mant);
+
+}
+
+/* ....................... end of G726_floatb() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_fmult (short *a, short *srn, short *wa);
+        ~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Multiply predictor coefficients with corresponding  quantized
+        difference signal or reconstructed  signal. multiplication is
+        done in floating piont format
+
+ 	Inputs:  a (or b), srn (or dqn)
+ 	Outputs:  wa (or wb)
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_fmult(An, SRn, WAn)
+short *An, *SRn, *WAn;
+{
+  long anmag, anexp, wanmag, anmant;
+  long wanexp, srnexp, an, ans, wanmant, srnmant;
+  long wan, wans, srns, srn1;
+
+  /* Preamble */
+  an = *An & 65535;
+  srn1 = *SRn & 65535;
+
+  /* Sign */
+  ans = an & 32768;
+  ans = (ans >> 15);
+
+  /* Convert 2's complement to signed magnitude */
+  anmag = (ans == 0) ? (an >> 2) : ((16384 - (an >> 2)) & 8191);
+
+  /* Exponent */
+  if (anmag >= 4096)
+    anexp = 13;
+  else if (anmag >= 2048)
+    anexp = 12;
+  else if (anmag >= 1024)
+    anexp = 11;
+  else if (anmag >= 512)
+    anexp = 10;
+  else if (anmag >= 256)
+    anexp = 9;
+  else if (anmag >= 128)
+    anexp = 8;
+  else if (anmag >= 64)
+    anexp = 7;
+  else if (anmag >= 32)
+    anexp = 6;
+  else if (anmag >= 16)
+    anexp = 5;
+  else if (anmag >= 8)
+    anexp = 4;
+  else if (anmag >= 4)
+    anexp = 3;
+  else if (anmag >= 2)
+    anexp = 2;
+  else if (anmag == 1)
+    anexp = 1;
+  else
+    anexp = 0;
+
+  /* Compute mantissa w/a 1 in the most sig. bit */
+  anmant = (anmag == 0) ? (1 << 5) : ((anmag << 6) >> anexp);
+
+  /* Split floating point word into sign, exponent and mantissa */
+  srns = (srn1 >> 10);
+  srnexp = (srn1 >> 6) & 15;
+  srnmant = srn1 & 63;
+
+  /* Floating point multiplication */
+  wans = srns ^ ans;
+  wanexp = srnexp + anexp;
+  wanmant = ((srnmant * anmant) + 48) >> 4;
+
+  /* Convert floating point to magnitude */
+  wanmag = (wanexp <= 26) ?
+    (wanmant << 7) >> (26 - wanexp) :
+    ((wanmant << 7) << (wanexp - 26)) & 32767;
+
+  /* Convert mag. to 2's complement */
+  wan = (wans == 0) ? wanmag : ((65536 - wanmag) & 65535);
+
+  *WAn = (short) wan;
+
+}
+
+/* ....................... end of G726_fmult() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_limc (short *a2t, short *a2p);
+        ~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Limits on a2 coefficient of second order  predictor.
+
+ 	Inputs:   a2t
+ 	Output:   a2p
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+
+void G726_limc(a2t, a2p)
+short *a2t, *a2p;
+{
+  long a2p1, a2t1, a2ll, a2ul;
+
+  a2t1 = *a2t & 65535;
+
+  a2ul = 12288;                 /* Upper limit of +.75 */
+  a2ll = 53248;                 /* Lower limit of -.75 */
+
+  if (a2t1 >= 32768 && a2t1 <= a2ll)
+    a2p1 = a2ll;
+  else if (a2t1 >= a2ul && a2t1 <= 32767)
+    a2p1 = a2ul;
+  else
+    a2p1 = a2t1;
+
+  *a2p = (short) a2p1;
+
+}
+
+/* ....................... end of G726_limc() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_limd (short *a1t, short *a2p, short *a1p);
+        ~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Limits on a1 coefficient of second order  predictor.
+
+ 	Inputs:   a1t, a2p
+ 	Output:   a1p
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_limd(a1t, a2p, a1p)
+short *a1t, *a2p, *a1p;
+{
+  long a1p1, a2p1, a1t1, ome, a1ll, a1ul;
+
+  /* Preamble */
+  a1t1 = *a1t & 65535;
+  a2p1 = *a2p & 65535;
+
+  /* (1-epsilon), where epsilon = (1/16) */
+  ome = 15360;
+
+  /* Compute upper limit */
+  a1ul = (ome + 65536 - a2p1) & 65535;
+
+  /* Compute lower limit */
+  a1ll = (a2p1 + 65536 - ome) & 65535;
+
+  if (a1t1 >= 32768 && a1t1 <= a1ll)
+    a1p1 = a1ll;
+  else if (a1t1 >= a1ul && a1t1 <= 32767)
+    a1p1 = a1ul;
+  else
+    a1p1 = a1t1;
+
+  *a1p = (short) a1p1;
+
+}
+
+/* ....................... end of G726_limd() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_trigb (short *tr, short *ap, short *ar);
+        ~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Predictor trigger block.
+
+ 	Inputs: tr, ap (ou bp ou tdp)
+ 	Output: ar (ou br ou tdr)
+
+        Return value:          none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_trigb(tr, ap, ar)
+short *tr, *ap, *ar;
+{
+  *ar = (*tr == 0) ? *ap : 0;
+
+}
+
+/* ....................... end of G726_trigb() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_upa1 (short *pk0, short *pk1, short *a1,
+        ~~~~~~~~~~~~~~  short *sigpk, short *a1t);
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Update a1 coefficient of second order predictor.
+
+ 	Inputs:   pk0, pk1, a1, sigpk
+ 	Output:   a1t
+
+        Return value:          none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_upa1(pk0, pk1, a1, sigpk, a1t)
+short *pk0, *pk1, *a1, *sigpk, *a1t;
+{
+  long a11, a1s, ua1;
+  long ash;
+  short pks;
+  long uga1, ula1;
+
+  /* Preamble */
+  a11 = *a1 & 65535;
+
+  pks = (*pk0) ^ (*pk1);
+
+  /* Gain is +/- (3/256) */
+  uga1 = (*sigpk == 1) ? 0 : ((pks == 0) ? 192 : 65344);
+
+  a1s = (a11 >> 15);
+
+  /* Leak factor is (1/256) */
+  ash = (a11 >> 8);
+  ula1 = ((a1s == 0) ? (65536 - ash) : (65536 - (ash + 65280))) & 65535;
+
+  /* Compute update */
+  ua1 = (uga1 + ula1) & 65535;
+  *a1t = (short) ((a11 + ua1) & 65535);
+
+}
+
+/* ....................... end of G726_upa1() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_upa2 (short *pk0, short *pk1, short *pk2,
+        ~~~~~~~~~~~~~~  short *a2, short *a1, short *sigpk, short *a2t);
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Update a2 coefficient of second order predictor.
+
+ 	Inputs:   pk0, pk1, pk2, a2, a1, sigpk
+ 	Output:   a2t
+
+        Return value:          none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_upa2(pk0, pk1, pk2, a2, a1, sigpk, a2t)
+short *pk0, *pk1, *pk2, *a2, *a1, *sigpk, *a2t;
+{
+  long uga2a, uga2b, uga2s;
+  long a11, a21, fa, fa1;
+  short a1s, a2s;
+  long ua2;
+  long uga2, ula2;
+  short pks1, pks2;
+
+  /* Preamble */
+  a11 = *a1 & 65535;
+  a21 = *a2 & 65535;
+
+  /* 1 bit xors */
+  pks1 = (*pk0 ^ *pk1);
+  pks2 = (*pk0 ^ *pk2);
+
+  uga2a = (pks2 == 0) ? 16384 : 114688;
+
+  a1s = (*a1 >> 15);
+
+  /* Implement f(a1) w/ limiting at +/-(1/2) */
+  if (a1s == 0)
+    fa1 = (a11 <= 8191) ? (a11 << 2) : (8191 << 2);
+  else
+    fa1 = (a11 >= 57345) ? ((a11 << 2) & 131071) : (24577 << 2);
+
+  /* Attach sign to the result of f(a1) */
+  fa = (pks1) ? fa1 : ((131072 - fa1) & 131071);
+
+  uga2b = (uga2a + fa) & 131071;
+  uga2s = (uga2b >> 16);
+
+  uga2 = (*sigpk == 1) ? 0 :
+    ((uga2s) ? ((uga2b >> 7) + 64512) : (uga2b >> 7));
+
+  a2s = (*a2 >> 15);
+
+  ula2 = (a2s == 0) ? (65536 - (a21 >> 7)) & 65535 :
+    (65536 - ((a21 >> 7) + 65024)) & 65535;
+
+  /* Compute update */
+  ua2 = (uga2 + ula2) & 65535;
+  *a2t = (short) ((a21 + ua2) & 65535);
+
+}
+
+/* ....................... end of G726_upa2() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_upb (short rate, short *u, short *b, short *dq, short *bp);
+        ~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Update for coefficients of sixth order predictor.
+
+ 	Inputs:    u, b, dq, rate
+ 	Output:    bp
+
+        Return value:          none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_upb(rate, u, b, dq, bp)
+short *u, *b, *dq, *bp;
+short rate;
+{
+  short dqmag;
+  long bb, bs, ub;
+  long ugb, ulb;
+  short param;
+  short leak;
+
+  /* Preamble */
+  bb = *b & 65535;
+
+  dqmag = *dq & 32767;
+  if (rate != 5) {
+    leak = 8;
+    param = 65280;
+  } else {
+    leak = 9;
+    param = 65408;
+  }
+  /* gain is 0 or +/- (1/128) */
+  ugb = (dqmag == 0) ? 0 : ((*u == 0) ? 128 : 65408);
+
+  bs = (bb >> 15);
+
+  /* Leak factor is (1/256 or 1/512 for 40 kbit/s) */
+
+  ulb = (bs == 0) ?
+    ((65536 - (bb >> leak)) & 65535) :
+    ((65536 - ((bb >> leak) + param)) & 65535);
+
+  /* Compute update */
+  ub = (ugb + ulb) & 65535;
+/*  aux = bb + ub;*/
+
+  *bp = (short) ((bb + ub) & 65535);
+
+}
+
+/* ....................... end of G726_upb() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_xor (short *dqn, short *dq, short *u);
+        ~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        One bit "exclusive or" of sign of difference  signal and sign
+        of delayed difference signal.
+
+ 	Inputs:    dqn, dq
+ 	Output:    u
+
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_xor(dqn, dq, u)
+short *dqn, *dq, *u;
+{
+  short dqns;
+  short dqs;
+
+  dqs = (*dq >> 15) & 1;
+
+  dqns = (*dqn >> 10);
+
+  *u = (dqs ^ dqns);
+
+}
+
+/* ....................... end of G726_xor() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_tone (short *a2p, short *tdp);
+        ~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Partial band signal detection.
+
+ 	Inputs: a2p
+ 	Output: tdp
+
+        Return value:          none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_tone(a2p, tdp)
+short *a2p, *tdp;
+{
+  long a2p1;
+
+  a2p1 = *a2p & 65535;
+
+  *tdp = (a2p1 >= 32768 && a2p1 < 53760) ? 1 : 0;
+
+}
+
+/* ....................... end of G726_tone() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_trans (short *td, long *yl, short *dq, short *tr);
+        ~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Transition detector.
+
+ 	Inputs: td, yl, dq
+ 	Output: tr
+
+        Return value:          none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_trans(td, yl, dq, tr)
+short *td;
+long *yl;
+short *dq, *tr;
+{
+  short dqmag;
+  long dqthr;
+  short ylint;
+  long dqmag1;
+  short ylfrac;
+  long thr1, thr2;
+
+  dqmag = *dq & 32767;
+
+  ylint = (*yl >> 15);
+
+  ylfrac = (*yl >> 10) & 31;
+
+  thr1 = (ylfrac + 32) << ylint;
+
+  thr2 = (ylint > 9) ? 31744 : thr1;
+
+  dqthr = (thr2 + (thr2 >> 1)) >> 1;
+
+  dqmag1 = dqmag;
+
+  *tr = (dqmag1 > dqthr && *td == 1) ? 1 : 0;
+
+}
+
+/* ....................... end of G726_trans() ....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_compress (short *sr, char *law, short *sp);
+        ~~~~~~~~~~~~~~~~~~
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Convert from uniform pcm  to either a-law or u-law pcm
+
+        Inputs:   sr, law
+        Output:   sp
+
+        Return value:  none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+                        <tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+                        <tdsimao@venus.cpqd.ansp.br>
+        24.Jan.00 v2.0  Corrected im calculation that caused incorrect 
+                        processing of test vector ri40fa. Corrected
+                        code provided by Jayesh Patel <jayesh@dspse.com>. 
+			Verified by <simao.campos@labs.comsat.com>
+ ----------------------------------------------------------------------
+*/
+void G726_compress(sr, law, sp)
+short *sr;
+char *law;
+short *sp;
+{
+  short imag, iesp, ofst;
+  short ofst1;
+  long i;
+  long im;
+  short is;
+  long srr;
+
+  is = (*sr >> 15);
+  srr = (*sr & 65535);
+
+  /* Convert 2-complement to signed magnitude */
+  im = (is == 0) ? srr : ((65536 - srr) & 32767);
+
+  /* Compress ... */
+  if (*law == '1') {
+
+    /* Next line added by J.Patel to fix a with test vector ri40fa.o */
+    im = (*sr == -32768) ? 2 : im;      /* *** */
+
+    imag = (is == 0) ? (im >> 1) : ((im + 1) >> 1);
+
+    if (is)
+      --imag;
+
+    /* Saturation */
+    if (imag > 4095)
+      imag = 4095;
+
+    iesp = 7;
+    for (i = 1; i <= 7; ++i) {
+      imag += imag;
+      if (imag >= 4096)
+        break;
+      iesp = 7 - i;
+    }
+
+    imag &= 4095;
+
+    imag = (imag >> 8);
+    *sp = (is == 0) ? imag + (iesp << 4) : imag + (iesp << 4) + 128;
+
+    /* Sign bit inversion */
+    *sp ^= 128;
+  } else {
+    imag = im;
+
+    if (imag > 8158)
+      imag = 8158;              /* Saturation */
+
+    ++imag;
+    iesp = 0;
+    ofst = 31;
+
+    if (imag > ofst) {
+      for (iesp = 1; iesp <= 8; ++iesp) {
+        ofst1 = ofst;
+        ofst += (1 << (iesp + 5));
+        if (imag <= ofst)
+          break;
+      }
+      imag -= ofst1 + 1;
+    }
+
+    imag /= (1 << (iesp + 1));
+
+    *sp = (is == 0) ? (imag + (iesp << 4)) : (imag + (iesp << 4) + 128);
+
+    /* Sign bit inversion */
+    *sp ^= 128;
+    *sp ^= 127;
+  }
+
+}
+
+/* ....................... end of G726_compress()....................... */
+
+
+/*
+ ----------------------------------------------------------------------
+
+        void G726_sync (short rate, short *i, short *sp, short *dlnx,
+        ~~~~~~~~~~~~~~  short *dsx, char *law, short *sd);
+
+        Description:
+        ~~~~~~~~~~~~
+
+        Re-encode output pcm sample in decoder for  synchronous tandem
+        coding.
+
+ 	Inputs:   i, sp, dlnx, dsx, law, rate
+ 	Output:   sd
+
+        Return value:          none.
+        ~~~~~~~~~~~~~
+
+        Prototype:   in g726.h
+        ~~~~~~~~~~
+
+        History:
+        ~~~~~~~~
+        31.Jan.91 v1.0f Release of 1st Fortran version to UGST.
+        		<tdsindi@venus.cpqd.ansp.br>
+        13.Feb.92 v1.0c 1st version in C translated from Fortran (f2c)
+        		<tdsimao@venus.cpqd.ansp.br>
+
+ ----------------------------------------------------------------------
+*/
+void G726_sync(rate, i, sp, dlnx, dsx, law, sd)
+short *i, *sp, *dlnx, *dsx;
+char *law;
+short *sd;
+short rate;
+{
+  short mask, id, im, is, ss;
+
+  if (rate == 4) {
+    is = (*i >> 3);
+
+    im = (is == 0) ? (*i + 8) : (*i & 7);
+
+    /* Find value of `id' as in Table 17/G.726 */
+    if (*dlnx >= 3972)
+      id = 9;
+    else if (*dlnx >= 2048)
+      id = 7;
+    else if (*dlnx >= 400)
+      id = 15;
+    else if (*dlnx >= 349)
+      id = 14;
+    else if (*dlnx >= 300)
+      id = 13;
+    else if (*dlnx >= 246)
+      id = 12;
+    else if (*dlnx >= 178)
+      id = 11;
+    else if (*dlnx >= 80)
+      id = 10;
+    else
+      id = 9;
+
+    /* Account for the negative part of the table */
+    if (*dsx)
+      id = 15 - id;
+
+    if (id == 8)
+      id = 7;
+  }                             /* ............... end of 32 kbit part
+                                 * ................. */
+  else if (rate == 3) {
+    is = (*i >> 2);
+
+    im = (is == 0) ? (*i + 4) : (*i & 3);
+
+    /* Find value of `id' as in the Table 18/G.726 */
+    if (*dlnx >= 2048)
+      id = 3;
+    else if (*dlnx >= 331)
+      id = 7;
+    else if (*dlnx >= 218)
+      id = 6;
+    else if (*dlnx >= 8)
+      id = 5;
+    else if (*dlnx >= 0)
+      id = 3;
+
+
+    if (*dsx)
+      id = 7 - id;
+
+    if (id == 4)
+      id = 3;
+  }                             /* ............... end of 24 kbit part
+                                 * ................. */
+  else if (rate == 2) {
+    is = (*i >> 1);
+
+    im = (is == 0) ? (*i + 2) : (*i & 1);
+
+    /* Find value of `id' as in the Table 19/G.726 */
+    if (*dlnx >= 2048)
+      id = 2;
+    else if (*dlnx >= 261)
+      id = 3;
+    else if (*dlnx >= 0)
+      id = 2;
+
+    if (*dsx)
+      id = 3 - id;
+
+  }                             /* ............... end of 16 kbit part
+                                 * ................. */
+  else {
+    is = (*i >> 4);
+
+    im = (is == 0) ? (*i + 16) : (*i & 15);
+
+    /* Find value of `id' as in the Table 16/G.726 */
+
+    if (*dlnx >= 4080)
+      id = 18;
+    else if (*dlnx >= 3974)
+      id = 17;
+    else if (*dlnx >= 2048)
+      id = 15;
+    else if (*dlnx >= 553)
+      id = 31;
+    else if (*dlnx >= 528)
+      id = 30;
+    else if (*dlnx >= 502)
+      id = 29;
+    else if (*dlnx >= 475)
+      id = 28;
+    else if (*dlnx >= 445)
+      id = 27;
+    else if (*dlnx >= 413)
+      id = 26;
+    else if (*dlnx >= 378)
+      id = 25;
+    else if (*dlnx >= 339)
+      id = 24;
+    else if (*dlnx >= 298)
+      id = 23;
+    else if (*dlnx >= 250)
+      id = 22;
+    else if (*dlnx >= 198)
+      id = 21;
+    else if (*dlnx >= 139)
+      id = 20;
+    else if (*dlnx >= 68)
+      id = 19;
+    else if (*dlnx >= 0)
+      id = 18;
+
+    if (*dsx)
+      id = 31 - id;
+
+    if (id == 16)
+      id = 15;
+
+  }                             /* ............... end of 40 kbit part
+                                 * ................. */
+
+  /* Choose sd as sp, sp+ or sp- */
+
+  ss = (*sp & 128) >> 7;
+  mask = (*sp & 127);
+
+  if (*law == '1') {            /* ......... A-law */
+    if (id > im && ss == 1 && mask == 0)
+      ss = 0;
+    else if (id > im && ss == 1 && mask != 0)
+      mask--;
+    else if (id > im && ss == 0 && mask != 127)
+      mask++;
+    else if (id < im && ss == 1 && mask != 127)
+      mask++;
+    else if (id < im && ss == 0 && mask == 0)
+      ss = 1;
+    else if (id < im && ss == 0 && mask != 0)
+      mask--;
+  } else {                      /* ......... u-law */
+    if (id > im && ss == 1 && mask == 127) {
+      ss = 0;
+      mask--;
+    } else if (id > im && ss == 1 && mask != 127)
+      mask++;
+    else if (id > im && ss == 0 && mask != 0)
+      mask--;
+    else if (id < im && ss == 1 && mask != 0)
+      mask--;
+    else if (id < im && ss == 0 && mask == 127)
+      ss = 1;
+    else if (id < im && ss == 0 && mask != 127)
+      mask++;
+  }
+
+  *sd = mask + (ss << 7);
+
+}
+
+/* ........................ end of G726_sync() ........................  */
+
+/* ************************* END OF G726.C ************************* */

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