/*
 * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
 * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
 * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
 */

/* $Header: /home/kbs/jutta/src/gsm/gsm-1.0/src/RCS/code.c,v 1.1 1992/10/28 00:15:50 jutta Exp $ */

#include	"config.h"


#ifdef	HAS_STDLIB_H
#include	<stdlib.h>
#include        <string.h>
#else
#	include "proto.h"
extern char *memcpy P((char *, char *, int));
#endif

#include	"private.h"
#include	"gsm.h"
#include	"proto.h"

/* 
 *  4.2 FIXED POINT IMPLEMENTATION OF THE RPE-LTP CODER 
 */

void Gsm_Coder P8((S, s, LARc, Nc, bc, Mc, xmaxc, xMc), struct gsm_state *S, word * s,  /* [0..159] samples                     IN      */
/*
 * The RPE-LTD coder works on a frame by frame basis.  The length of
 * the frame is equal to 160 samples.  Some computations are done
 * once per frame to produce at the output of the coder the
 * LARc[1..8] parameters which are the coded LAR coefficients and 
 * also to realize the inverse filtering operation for the entire
 * frame (160 samples of signal d[0..159]).  These parts produce at
 * the output of the coder:
 */
  word * LARc,                  /* [0..7] LAR coefficients              OUT     */
/*
 * Procedure 4.2.11 to 4.2.18 are to be executed four times per
 * frame.  That means once for each sub-segment RPE-LTP analysis of
 * 40 samples.  These parts produce at the output of the coder:
 */
  word * Nc,                    /* [0..3] LTP lag                       OUT     */
  word * bc,                    /* [0..3] coded LTP gain                OUT     */
  word * Mc,                    /* [0..3] RPE grid selection            OUT     */
  word * xmaxc,                 /* [0..3] Coded maximum amplitude       OUT     */
  word * xMc                    /* [13*4] normalized RPE samples        OUT     */
  )
{
  int k;
  word *dp = S->dp0 + 120;      /* [ -120...-1 ] */
  word *dpp = dp;               /* [ 0...39 ]    */

  static word e[50] = { 0 };

  word so[160];

  Gsm_Preprocess(S, s, so);
  Gsm_LPC_Analysis(S, so, LARc);
  Gsm_Short_Term_Analysis_Filter(S, LARc, so);

  for (k = 0; k <= 3; k++, xMc += 13) {

    Gsm_Long_Term_Predictor(S, so + k * 40,     /* d      [0..39] IN  */
      dp,                       /* dp  [-120..-1] IN  */
      e + 5,                    /* e      [0..39] OUT */
      dpp,                      /* dpp    [0..39] OUT */
      Nc++, bc++);

    Gsm_RPE_Encoding(S, e + 5,  /* e      ][0..39][ IN/OUT */
      xmaxc++, Mc++, xMc);
    /*
     * Gsm_Update_of_reconstructed_short_time_residual_signal
     *                      ( dpp, e + 5, dp );
     */

    {
      register int i;
      register longword ltmp;
      for (i = 0; i <= 39; i++)
        dp[i] = GSM_ADD(e[5 + i], dpp[i]);
    }
    dp += 40;
    dpp += 40;

  }
  (void) memcpy((char *) S->dp0, (char *) (S->dp0 + 160),
    120 * sizeof(*S->dp0));
}
