os/mm/mmlibs/mmfw/Codecs/Src/Gsm610CodecCommon/rpeltp.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include "types.h"
sl@0
    17
#include "rpeltp.h"
sl@0
    18
#include "basicop.h"
sl@0
    19
#include "tables.h"
sl@0
    20
#include "gsm610fr.h"
sl@0
    21
sl@0
    22
/*
sl@0
    23
** Static variables are allocated as globals in order to make it
sl@0
    24
** possible to clear them in run time (reset codec). This might be
sl@0
    25
** useful e.g. in possible EC code
sl@0
    26
*/
sl@0
    27
sl@0
    28
sl@0
    29
/*
sl@0
    30
** void reset_encoder(CGSM610FR_Encoder* aEncoder)
sl@0
    31
**
sl@0
    32
** Function clears encoder variables.
sl@0
    33
** Input:
sl@0
    34
**   None
sl@0
    35
** Output:
sl@0
    36
**   Clear z1, L_z2, mp, LARpp_Prev[0..7], u[0..7], dp[0..119]
sl@0
    37
** Return value:
sl@0
    38
**   None
sl@0
    39
*/
sl@0
    40
void reset_encoder(CGSM610FR_Encoder* aEncoder)
sl@0
    41
{
sl@0
    42
  int i;
sl@0
    43
sl@0
    44
  aEncoder->z1 = 0;
sl@0
    45
  aEncoder->L_z2 = 0;
sl@0
    46
  aEncoder->mp = 0;
sl@0
    47
sl@0
    48
  for ( i = 0; i <= 7; i++ )
sl@0
    49
    aEncoder->LARpp_prev[i] = 0;
sl@0
    50
  for ( i = 0; i <= 7; i++ )
sl@0
    51
    aEncoder->u[i] = 0;
sl@0
    52
  for ( i = 0; i <= 119; i++ )
sl@0
    53
    aEncoder->dp[i] = 0;
sl@0
    54
}
sl@0
    55
sl@0
    56
sl@0
    57
/*
sl@0
    58
** void reset_decoder(CGSM610FR_Encoder* aDecoder)
sl@0
    59
**
sl@0
    60
** Function clears decoder variables.
sl@0
    61
** Input:
sl@0
    62
**   None
sl@0
    63
** Output:
sl@0
    64
**   Clear LARpp_Prev[0..7], v[0..8], drp[0..119], nrp
sl@0
    65
** Return value:
sl@0
    66
**   None
sl@0
    67
*/
sl@0
    68
void reset_decoder(CGSM610FR_Decoder* aDecoder)
sl@0
    69
{
sl@0
    70
  int i;
sl@0
    71
sl@0
    72
  for ( i = 0; i <= 7; i++ )
sl@0
    73
    aDecoder->LARrpp_prev[i] = 0;
sl@0
    74
  for ( i = 0; i <= 8; i++ )
sl@0
    75
    aDecoder->v[i] = 0;
sl@0
    76
  aDecoder->msr = 0;
sl@0
    77
  for ( i = 0; i <= 119; i++ )
sl@0
    78
    aDecoder->drp[i] = 0;
sl@0
    79
  aDecoder->nrp = 40;
sl@0
    80
}
sl@0
    81
sl@0
    82
/*
sl@0
    83
#  4.2.1. Downscaling of the input signal
sl@0
    84
#
sl@0
    85
#  4.2.2. Offset compensation
sl@0
    86
#
sl@0
    87
#  This part implements a high-pass filter and requires extended
sl@0
    88
#  arithmetic precision for the recursive part of this filter.
sl@0
    89
#
sl@0
    90
#  The input of this procedure is the array so[0..159] and the output
sl@0
    91
#  array sof[0..159].
sl@0
    92
#
sl@0
    93
#  Keep z1 and L_z2 in memory for the next frame.
sl@0
    94
#  Initial value: z1=0; L_z2=0;
sl@0
    95
sl@0
    96
@  Downscaling and offset compensation are combined in order to spare
sl@0
    97
@  unnecessary data moves.
sl@0
    98
*/
sl@0
    99
sl@0
   100
void prepr( CGSM610FR_Encoder* aEncoder, int2 sof[], int2 so[] )
sl@0
   101
{
sl@0
   102
  int k;
sl@0
   103
sl@0
   104
  int2 msp;
sl@0
   105
  int2 temp;
sl@0
   106
  int4 L_s2;
sl@0
   107
/*
sl@0
   108
# 4.2.1. Downscaling of the input signal
sl@0
   109
# |== FOR k=0 to 159:
sl@0
   110
# | so[k] = sop[k] >> 3;
sl@0
   111
# | so[k] = so[k] << 2;
sl@0
   112
# |== NEXT k:
sl@0
   113
*/
sl@0
   114
sl@0
   115
/*
sl@0
   116
# |== FOR k = 0 to 159:
sl@0
   117
# |Compute the non-recursive part.
sl@0
   118
# | s1 = sub( so[k], z1 );
sl@0
   119
# | z1 = so[k];
sl@0
   120
# |Compute the recursive part.
sl@0
   121
# | L_s2 = s1;
sl@0
   122
# | L_s2 = L_s2 << 15;
sl@0
   123
# |Execution of a 31 by 16 bits multiplication.
sl@0
   124
# | msp = L_z2 >> 15;
sl@0
   125
# | lsp = L_sub( L_z2, ( msp << 15 ) );
sl@0
   126
# | temp = mult_r( lsp, 32735 );
sl@0
   127
# | L_s2 = L_add( L_s2, temp );
sl@0
   128
# | L_z2 = L_add( L_mult( msp, 32735 ) >> 1, L_s2 );
sl@0
   129
# |Compute sof[k] with rounding.
sl@0
   130
# | sof[k] = L_add( L_z2, 16384 ) >> 15;
sl@0
   131
# |== NEXT k:
sl@0
   132
*/
sl@0
   133
  for (k=0; k <= 159; k++) {
sl@0
   134
sl@0
   135
    /* Downscaling */
sl@0
   136
    temp = shl( shr( so[k], 3 ), 2 );
sl@0
   137
sl@0
   138
    /* Compute the non-recursive part. */
sl@0
   139
    /* Compute the recursive part. */
sl@0
   140
sl@0
   141
    L_s2 = L_deposit_l( sub( temp, aEncoder->z1 ) );
sl@0
   142
    aEncoder->z1 = temp;
sl@0
   143
sl@0
   144
sl@0
   145
    L_s2 = L_shl( L_s2, 15 );
sl@0
   146
    /* Execution of a 31 by 16 bits multiplication. */
sl@0
   147
    msp = extract_l( L_shr( aEncoder->L_z2, 15 ) );
sl@0
   148
    temp = extract_l( L_sub( aEncoder->L_z2, L_shl( L_deposit_l( msp ), 15 ) ) );
sl@0
   149
    temp = mult_r( temp, 32735 );
sl@0
   150
    L_s2 = L_add( L_s2, L_deposit_l( temp ) );
sl@0
   151
    aEncoder->L_z2 = L_add( L_shr( L_mult( msp, 32735 ), 1 ), L_s2 );
sl@0
   152
    /* Compute sof[k] with rounding. */
sl@0
   153
    sof[k] = extract_l( L_shr( L_add( aEncoder->L_z2, (int4) 16384 ), 15 ) );
sl@0
   154
  }
sl@0
   155
}
sl@0
   156
sl@0
   157
/*
sl@0
   158
#  4.2.3. Preemphasis
sl@0
   159
#
sl@0
   160
#  Keep mp in memory for the next frame.
sl@0
   161
#  Initial value: mp=0;
sl@0
   162
*/
sl@0
   163
void preemp( CGSM610FR_Encoder* aEncoder, int2 s[], int2 sof[] )
sl@0
   164
{
sl@0
   165
  int k;
sl@0
   166
  int2 temp;
sl@0
   167
/*
sl@0
   168
# |== FOR k=0 to 159:
sl@0
   169
# | s[k] = add( sof[k], mult_r( mp, -28180 ) );
sl@0
   170
# | mp = sof[k];
sl@0
   171
# |== NEXT k:
sl@0
   172
*/
sl@0
   173
sl@0
   174
/*
sl@0
   175
@ Reverse looping in order to make it possible to
sl@0
   176
@ update filter delay mp only at the end of the loop
sl@0
   177
*/
sl@0
   178
  temp = sof[159]; /* make overwrite possible */
sl@0
   179
sl@0
   180
  for ( k = 159; k >= 1; k-- )
sl@0
   181
    s[k] = add( sof[k], mult_r( sof[k-1], -28180 ) );
sl@0
   182
sl@0
   183
  s[0] = add( sof[0], mult_r( aEncoder->mp, -28180 ) );
sl@0
   184
sl@0
   185
  aEncoder->mp = temp;
sl@0
   186
}
sl@0
   187
sl@0
   188
/*
sl@0
   189
#  4.2.4. Autocorrelation
sl@0
   190
#
sl@0
   191
#  The goal is to compute the array L_ACF[k]. The signal s[i] must be
sl@0
   192
#  scaled in order to avoid an overflow situation.
sl@0
   193
*
sl@0
   194
* output:
sl@0
   195
*       scalauto (return value)
sl@0
   196
*
sl@0
   197
*/
sl@0
   198
int2 autoc( int4 L_ACF[], int2 s[] )
sl@0
   199
{
sl@0
   200
  int k, i;
sl@0
   201
sl@0
   202
  int2 smax;
sl@0
   203
  int2 temp;
sl@0
   204
  int4 L_temp2;
sl@0
   205
  int2 scalauto;
sl@0
   206
/*
sl@0
   207
# Dynamic scaling of the array s[0..159].
sl@0
   208
#
sl@0
   209
# Search for the maximum.
sl@0
   210
#
sl@0
   211
# smax=0;
sl@0
   212
# |== FOR k = 0 to 159:
sl@0
   213
# | temp = abs( s[k] );
sl@0
   214
# | IF ( temp > smax ) THEN smax = temp;
sl@0
   215
# |== NEXT k;
sl@0
   216
*/
sl@0
   217
  smax = 0;
sl@0
   218
  for ( k = 0; k <= 159; k++ ) {
sl@0
   219
    temp = abs_s( s[k] );
sl@0
   220
    if ( sub( temp, smax ) > 0 )
sl@0
   221
      smax = temp;
sl@0
   222
  }
sl@0
   223
/*
sl@0
   224
# Computation of the scaling factor.
sl@0
   225
#
sl@0
   226
# IF ( smax == 0 ) THEN scalauto = 0;
sl@0
   227
#    ELSE scalauto = sub( 4, norm( smax << 16 ) );
sl@0
   228
*/
sl@0
   229
  if ( smax == 0 )
sl@0
   230
    scalauto = 0;
sl@0
   231
  else
sl@0
   232
    scalauto = sub( 4, norm_l( L_deposit_h( smax ) ) );
sl@0
   233
/* 
sl@0
   234
# Scaling of the array s[0..159].
sl@0
   235
# IF ( scalauto > 0 ) THEN
sl@0
   236
#    | temp = 16384 >> sub( scalauto, 1 );
sl@0
   237
#    |== FOR k=0 to 159:
sl@0
   238
#    |    s[k] = mult_r( s[k], temp );
sl@0
   239
#    |== NEXT k:
sl@0
   240
*/
sl@0
   241
  if ( scalauto > 0 ) {
sl@0
   242
    temp = shr( 16384, sub( scalauto, 1 ) );
sl@0
   243
    for ( k = 0; k <= 159; k++ ) 
sl@0
   244
      s[k] = mult_r( s[k], temp );
sl@0
   245
  }
sl@0
   246
/*
sl@0
   247
# Compute the L_ACF[..].
sl@0
   248
# |== FOR k=0 to 8:
sl@0
   249
# |     L_ACF[k] = 0;
sl@0
   250
# |==== FOR i=k to 159:
sl@0
   251
# |         L_temp = L_mult( s[i], s[i-k] );
sl@0
   252
# |         L_ACF[k] = L_add( L_ACF[k], L_temp );
sl@0
   253
# |==== NEXT i:
sl@0
   254
# |== NEXT k:
sl@0
   255
*/
sl@0
   256
  for ( k = 0; k <= 8; k++ ) {
sl@0
   257
    L_temp2 = 0;
sl@0
   258
    for ( i = k; i <= 159; i++ )
sl@0
   259
	L_temp2 = L_mac( L_temp2, s[i], s[i-k] );
sl@0
   260
sl@0
   261
    L_ACF[k] = L_temp2;
sl@0
   262
  }
sl@0
   263
/*
sl@0
   264
# Rescaling of the array s[0..159].
sl@0
   265
#
sl@0
   266
# IF ( scalauto > 0 ) THEN
sl@0
   267
#   |== FOR k = 0 to 159:
sl@0
   268
#   |    s[k] = s[k] << scalauto;
sl@0
   269
#   |== NEXT k:
sl@0
   270
*/
sl@0
   271
  if ( scalauto > 0 ) {
sl@0
   272
    for ( k = 0; k <= 159; k++ )
sl@0
   273
	 s[k] = shl( s[k], scalauto );
sl@0
   274
  }
sl@0
   275
  return(scalauto); /* scalauto is retuned to be used also in vad */
sl@0
   276
  
sl@0
   277
}
sl@0
   278
sl@0
   279
sl@0
   280
/*
sl@0
   281
#  4.2.5. Computation of the reflection coefficients
sl@0
   282
*/
sl@0
   283
void schur( int2 r[], int4 L_ACF[] )
sl@0
   284
{
sl@0
   285
  int k, i, n, m;
sl@0
   286
sl@0
   287
  int2 P[9];
sl@0
   288
  int2 K[7];
sl@0
   289
  int2 ACF[9];
sl@0
   290
  int2 normacf;
sl@0
   291
sl@0
   292
/*
sl@0
   293
# Schur recursion with 16 bits arithmetic
sl@0
   294
#
sl@0
   295
#    IF ( L_ACF[0] == 0 ) THEN
sl@0
   296
#                   |== FOR i=1 to 8:
sl@0
   297
#                   |    r[i] = 0;
sl@0
   298
#                   |== NEXT i:
sl@0
   299
#                   |    EXIT; / continue with section 4.2.6/
sl@0
   300
#    normacf = norm( L_ACF[0] ); / temp is spec replaced with normacf /
sl@0
   301
#    |== FOR k=0 to 8:
sl@0
   302
#    |    ACF[k] = ( L_ACF[k] << normacf ) >> 16;
sl@0
   303
#    |== NEXT k:
sl@0
   304
*/
sl@0
   305
  if ( L_ACF[0] == 0 ) {
sl@0
   306
    for ( i = 0; i <= 7; i++)
sl@0
   307
	 r[i] = 0;
sl@0
   308
    return; /* continue with section 4.2.6 */
sl@0
   309
  }
sl@0
   310
  normacf = norm_l( L_ACF[0] );
sl@0
   311
sl@0
   312
  for ( k = 0; k <= 8; k++ )
sl@0
   313
    ACF[k] = extract_h( L_shl( L_ACF[k], normacf ) );
sl@0
   314
/*
sl@0
   315
# Initialize array P[..] and K[..] for the recursion.
sl@0
   316
#
sl@0
   317
#    |== FOR i=1 to 7:
sl@0
   318
#    |    K[9-i] = ACF[i];
sl@0
   319
#    |== NEXT i:
sl@0
   320
#
sl@0
   321
#    |== FOR i=0 to 8:
sl@0
   322
#    |    P[i] = ACF[i];
sl@0
   323
#    |== NEXT i:
sl@0
   324
*/
sl@0
   325
  for ( i = 1; i <= 7; i++ )
sl@0
   326
    K[7-i] = ACF[i];
sl@0
   327
sl@0
   328
  for ( i = 0; i <= 8; i++ )
sl@0
   329
    P[i] = ACF[i];
sl@0
   330
/*
sl@0
   331
# Compute reflection coefficients
sl@0
   332
#    |== FOR n=1 to 8:
sl@0
   333
#    |    IF ( P[0] < abs( P[1] ) ) THEN
sl@0
   334
#    |                        |== FOR i=n to 8:
sl@0
   335
#    |                        |    r[i] = 0;
sl@0
   336
#    |                        |== NEXT i:
sl@0
   337
#    |                        |    EXIT; /continue with
sl@0
   338
#    |                        |    section 4.2.6./
sl@0
   339
#    |    r[n] = div( abs( P[1] ), P[0] );
sl@0
   340
#    |    IF ( P[1] > 0 ) THEN r[n] = sub( 0, r[n] );
sl@0
   341
#    |
sl@0
   342
#    |    IF ( n == 8 ) THEN EXIT; /continue with section 4.2.6/
sl@0
   343
#    |    Schur recursion
sl@0
   344
#    |    P[0] = add( P[0], mult_r( P[1], r[n] ) );
sl@0
   345
#    |==== FOR m=1 to 8-n:
sl@0
   346
#    |         P[m] = add( P[m+1], mult_r( K[9-m], r[n] ) );
sl@0
   347
#    |         K[9-m] = add( K[9-m], mult_r( P[m+1], r[n] ) );
sl@0
   348
#    |==== NEXT m:
sl@0
   349
#    |
sl@0
   350
#    |== NEXT n:
sl@0
   351
*/
sl@0
   352
sl@0
   353
  for ( n = 0; n <= 7; n++ )  {
sl@0
   354
    if ( sub( P[0], abs_s( P[1] ) ) < 0 ) {
sl@0
   355
	 for ( i = n; i <= 7; i++ )
sl@0
   356
	   r[i] = 0;
sl@0
   357
	 return; /* continue with section 4.2.6. */
sl@0
   358
    }
sl@0
   359
sl@0
   360
    if ( P[1] > 0 )
sl@0
   361
	 r[n] = negate( div_s( P[1], P[0] ) );
sl@0
   362
    else
sl@0
   363
	 r[n] = div_s( negate( P[1] ), P[0] );
sl@0
   364
sl@0
   365
    if ( sub(int2 (n), 7) == 0 )
sl@0
   366
	 return; /* continue with section 4.2.6 */
sl@0
   367
sl@0
   368
    /* Schur recursion */
sl@0
   369
    P[0] = add( P[0], mult_r( P[1], r[n] ) );
sl@0
   370
    for ( m = 1; m <= 7-n; m++ ) {
sl@0
   371
/*
sl@0
   372
 *    mac_r cannot be used because it rounds the result after
sl@0
   373
 *    addition when add( xx, mult_r ) rounds first the result
sl@0
   374
 *    of the product. That is why the following two lines cannot
sl@0
   375
 *    be used instead of the curently used lines.
sl@0
   376
 *
sl@0
   377
 *    P[m] = mac_r( L_deposit_l( P[m+1] ), K[7-m], r[n] );
sl@0
   378
 *    K[7-m] = mac_r( L_deposit_l( K[7-m] ), P[m+1], r[n] );
sl@0
   379
*/
sl@0
   380
      P[m] = add( P[m+1], mult_r( K[7-m], r[n] ) );
sl@0
   381
      K[7-m] = add( K[7-m], mult_r( P[m+1], r[n] ) );
sl@0
   382
    }
sl@0
   383
  }
sl@0
   384
}
sl@0
   385
sl@0
   386
/*
sl@0
   387
#  4.2.6. Transformation of reflection coefficients to Log.-Area Ratios -----
sl@0
   388
#
sl@0
   389
#  The following scaling for r[..] and LAR[..] has been used:
sl@0
   390
#
sl@0
   391
#  r[..] = integer( real_r[..]*32768. ); -1. <= real_r < 1.
sl@0
   392
#  LAR[..] = integer( real_LAR[..]*16384. );
sl@0
   393
#  with -1.625 <= real_LAR <= 1.625
sl@0
   394
*/
sl@0
   395
sl@0
   396
void larcomp( int2 LAR[], int2 r[] )
sl@0
   397
{
sl@0
   398
  int i;
sl@0
   399
sl@0
   400
  int2 temp;
sl@0
   401
/*
sl@0
   402
# Computation of the LAR[1..8] from the r[1..8]
sl@0
   403
#    |== FOR i=1 to 8:
sl@0
   404
#    |    temp = abs( r[i] );
sl@0
   405
#    |    IF ( temp < 22118 ) THEN temp = temp >> 1;
sl@0
   406
#    |         else if ( temp < 31130 ) THEN temp = sub( temp, 11059 );
sl@0
   407
#    |              else temp = sub( temp, 26112 ) << 2;
sl@0
   408
#    |    LAR[i] = temp;
sl@0
   409
#    |    IF ( r[i] < 0 ) THEN LAR[i] = sub( 0, LAR[i] );
sl@0
   410
#    |== NEXT i:
sl@0
   411
*/
sl@0
   412
  for ( i = 1; i <= 8; i++ ) {
sl@0
   413
	int j = i-1;
sl@0
   414
    temp = abs_s( r[j] );
sl@0
   415
sl@0
   416
    if ( sub( temp, 22118 ) < 0 )
sl@0
   417
      temp = shr( temp, 1 );
sl@0
   418
    else if ( sub( temp, 31130 ) < 0 )
sl@0
   419
      temp = sub( temp, 11059 );
sl@0
   420
    else
sl@0
   421
      temp = shl( sub( temp, 26112 ), 2 );
sl@0
   422
sl@0
   423
    if ( r[j] < 0 )
sl@0
   424
      LAR[j] = negate( temp );
sl@0
   425
    else
sl@0
   426
      LAR[j] = temp;
sl@0
   427
  }
sl@0
   428
}
sl@0
   429
sl@0
   430
sl@0
   431
/*
sl@0
   432
#  4.2.7. Quantization and coding of the Log.-Area Ratios
sl@0
   433
#
sl@0
   434
#  This procedure needs fpur tables; following equations give the
sl@0
   435
#  optimum scaling for the constants:
sl@0
   436
#
sl@0
   437
#  A[1..8]=integer( real_A[1..8]*1024 ); 8 values (see table 4.1)
sl@0
   438
#  B[1..8]=integer( real_B[1..8]*512 );  8 values (see table 4.1)
sl@0
   439
#  MAC[1..8]=maximum of the LARc[1..8];  8 values (see table 4.1)
sl@0
   440
#  MAC[1..8]=minimum of the LARc[1..8];  8 values (see table 4.1)
sl@0
   441
*/
sl@0
   442
sl@0
   443
void codlar( int2 LARc[], int2 LAR[] )
sl@0
   444
{
sl@0
   445
sl@0
   446
  int i;
sl@0
   447
sl@0
   448
  int2 temp;
sl@0
   449
/*
sl@0
   450
# Computation for quantizing and coding the LAR[1..8]
sl@0
   451
#
sl@0
   452
#    |== FOR i=1 to 8:
sl@0
   453
#    |    temp = mult( A[i], LAR[i] );
sl@0
   454
#    |    temp = add( temp, B[i] );
sl@0
   455
#    |    temp = add( temp, 256 );      for rounding
sl@0
   456
#    |    LARc[i] = temp >> 9;
sl@0
   457
#    |
sl@0
   458
#    | Check if LARc[i] lies between MIN and MAX
sl@0
   459
#    |    IF ( LARc[i] > MAC[i] ) THEN LARc[i] = MAC[i];
sl@0
   460
#    |    IF ( LARc[i] < MIC[i] ) THEN LARc[i] = MIC[i];
sl@0
   461
#    |    LARc[i] = sub( LARc[i], MIC[i] ); / See note below /
sl@0
   462
#    |== NEXT i:
sl@0
   463
#
sl@0
   464
# NOTE: The equation is used to make all the LARc[i] positive.
sl@0
   465
*/
sl@0
   466
  for ( i = 1; i <= 8; i++ ) {
sl@0
   467
	int j = i-1;
sl@0
   468
    temp = mult( A[j], LAR[j] );
sl@0
   469
    temp = add( temp, B[j] );
sl@0
   470
    temp = add( temp, 256 ); /* for rounding */
sl@0
   471
    temp = shr( temp, 9 );
sl@0
   472
    /* Check if LARc[i] lies between MIN and MAX */
sl@0
   473
    if ( sub( temp, MAC[j] ) > 0 )
sl@0
   474
      LARc[j] = sub( MAC[j], MIC[j] );
sl@0
   475
    else if ( sub( temp, MIC[j] ) < 0 )
sl@0
   476
      LARc[j] = 0;
sl@0
   477
    else
sl@0
   478
      LARc[j] = sub( temp, MIC[j] );
sl@0
   479
  }
sl@0
   480
}
sl@0
   481
sl@0
   482
sl@0
   483
/*
sl@0
   484
#  4.2.8 Decoding of the coded Log.-Area Ratios
sl@0
   485
#
sl@0
   486
#  This procedure requires for efficient implementation two variables.
sl@0
   487
#
sl@0
   488
#  INVA[1..8]=integer((32768*8)/(real_A[1..8]);    8 values (table 4.2)
sl@0
   489
#  MIC[1..8]=minimum value of the LARc[1..8];      8 values (table 4.2)
sl@0
   490
*/
sl@0
   491
sl@0
   492
void declar( int2 LARpp[], int2 LARc[] )
sl@0
   493
{
sl@0
   494
  int i;
sl@0
   495
sl@0
   496
  int2 temp1;
sl@0
   497
  int2 temp2;
sl@0
   498
/*
sl@0
   499
# Compute the LARpp[1..8].
sl@0
   500
#
sl@0
   501
#    |== FOR i=1 to 8:
sl@0
   502
#    |    temp1 = add( LARc[i], MIC[i] ) << 10; /See note below/
sl@0
   503
#    |    temp2 = B[i] << 1;
sl@0
   504
#    |    temp1 = sub( temp1, temp2 );
sl@0
   505
#    |    temp1 = mult_r( INVA[i], temp1 );
sl@0
   506
#    |    LARpp[i] = add( temp1, temp1 );
sl@0
   507
#    |== NEXT i:
sl@0
   508
#
sl@0
   509
# NOTE: The addition of MIC[i] is used to restore the sign of LARc[i].
sl@0
   510
*/
sl@0
   511
  for ( i = 1; i <= 8; i++ ) {
sl@0
   512
	int j = i-1;
sl@0
   513
    temp1 = shl( add( LARc[j], MIC[j] ), 10 );
sl@0
   514
    temp2 = shl( B[j], 1 );
sl@0
   515
    temp1 = sub( temp1, temp2 );
sl@0
   516
    temp1 = mult_r( INVA[j], temp1 );
sl@0
   517
    LARpp[j] = add( temp1, temp1 );
sl@0
   518
  }
sl@0
   519
}
sl@0
   520
sl@0
   521
sl@0
   522
/*
sl@0
   523
#  4.2.9. Computation of the quantized reflection coefficients
sl@0
   524
#
sl@0
   525
#  Within each frame of 160 anallyzed speech samples the short term
sl@0
   526
#  analysissss and synthesis filters operate with four different sets of
sl@0
   527
#  coefficients, derived from the previous set of decoded 
sl@0
   528
#  LARs(LARpp(j-1)) and the actual set of decoded LARs (LARpp(j)).
sl@0
   529
#
sl@0
   530
# 4.2.9.1 Interpolation of the LARpp[1..8] to get LARp[1..8]
sl@0
   531
*/
sl@0
   532
sl@0
   533
void cparc1( int2 LARp[], int2 LARpp_prev[], int2 LARpp[] )
sl@0
   534
{
sl@0
   535
  int i;
sl@0
   536
sl@0
   537
  int2 temp;
sl@0
   538
/*
sl@0
   539
#    FOR k_start=0 to k_end = 12.
sl@0
   540
#         
sl@0
   541
#    |==== FOR i=1 to 8:
sl@0
   542
#    |         LARp[i] = add( ( LARpp(j-1)[i] >> 2 ) ,( LARpp[i] >> 2 ) );
sl@0
   543
#    |         LARp[i] = add( LARp[i], ( LARpp(j-1)[i] >> 1 ) );
sl@0
   544
#    |==== NEXT i:
sl@0
   545
*/
sl@0
   546
  /* k_start=0 to k_end=12 */
sl@0
   547
sl@0
   548
  for ( i = 1; i <= 8; i++ ) {
sl@0
   549
	int j = i-1;
sl@0
   550
    temp = add( shr( LARpp_prev[j], 2 ), shr( LARpp[j], 2 ) );
sl@0
   551
    LARp[j] = add( temp, shr( LARpp_prev[j], 1 ) );
sl@0
   552
  }
sl@0
   553
}
sl@0
   554
 
sl@0
   555
sl@0
   556
void cparc2( int2 LARp[], int2 LARpp_prev[], int2 LARpp[] )
sl@0
   557
{
sl@0
   558
  int i;
sl@0
   559
  
sl@0
   560
/*
sl@0
   561
#    FOR k_start=13 to k_end = 26.
sl@0
   562
#    |==== FOR i=1 to 8:
sl@0
   563
#    |         LARp[i] = add( ( LARpp(j-1)[i] >> 1 ), ( LARpp[i] >> 1 ) );
sl@0
   564
#    |==== NEXT i:
sl@0
   565
*/
sl@0
   566
  /* k_start=13 to k_end=26 */
sl@0
   567
	
sl@0
   568
  for (i=1; i <= 8; i++) {
sl@0
   569
	int j = i-1;
sl@0
   570
    LARp[j] = add( shr( LARpp_prev[j], 1 ), shr( LARpp[j], 1 ) );
sl@0
   571
  }
sl@0
   572
}
sl@0
   573
sl@0
   574
sl@0
   575
void cparc3( int2 LARp[], int2 LARpp_prev[], int2 LARpp[] )
sl@0
   576
{
sl@0
   577
  int i;
sl@0
   578
sl@0
   579
  int2 temp;
sl@0
   580
  
sl@0
   581
/*
sl@0
   582
#    FOR k_start=27 to k_end = 39.
sl@0
   583
#    |==== FOR i=1 to 8:
sl@0
   584
#    |         LARp[i] = add( ( LARpp(j-1)[i] >> 2 ), ( LARpp[i] >> 2 ) );
sl@0
   585
#    |         LARp[i] = add( LARp[i], ( LARpp[i] >> 1 ) );
sl@0
   586
#    |==== NEXT i:
sl@0
   587
*/
sl@0
   588
  /* k_start=27 to k_end=39 */
sl@0
   589
	
sl@0
   590
  for ( i = 1; i <= 8; i++ ) {
sl@0
   591
	int j = i-1;
sl@0
   592
    temp = add( shr( LARpp_prev[j], 2 ), shr( LARpp[j], 2 ) );
sl@0
   593
    LARp[j] = add( temp, shr( LARpp[j], 1 ) );
sl@0
   594
  }
sl@0
   595
}
sl@0
   596
sl@0
   597
sl@0
   598
void cparc4( int2 LARp[], int2 LARpp_prev[], int2 LARpp[] )
sl@0
   599
{
sl@0
   600
  int i;
sl@0
   601
  
sl@0
   602
/*
sl@0
   603
#    FOR k_start=40 to k_end = 159.
sl@0
   604
#    |==== FOR i=1 to 8:
sl@0
   605
#    |         LARp[i] = LARpp[i];
sl@0
   606
#    |==== NEXT i:
sl@0
   607
*/
sl@0
   608
  /* k_start=40 to k_end=159 */
sl@0
   609
	
sl@0
   610
  for ( i = 1; i <= 8; i++ ) {
sl@0
   611
	int j = i-1;
sl@0
   612
    LARp[j] = LARpp[j];
sl@0
   613
    /* note new LARs saved here for next frame */
sl@0
   614
    LARpp_prev[j] = LARpp[j];
sl@0
   615
  }
sl@0
   616
sl@0
   617
}
sl@0
   618
sl@0
   619
sl@0
   620
/*
sl@0
   621
#  4.2.9.2 Computation of the rp[] from the interpolated LARp[]
sl@0
   622
#
sl@0
   623
#  The input of this procedure is the interpolated LARp[1..8] array. The
sl@0
   624
#  reflection coefficients, rp[i], are used in the analysis filter and in
sl@0
   625
#  the synthesis filter.
sl@0
   626
*/
sl@0
   627
sl@0
   628
void crp( int2 rp[], int2 LARp[] )
sl@0
   629
{
sl@0
   630
  int i;
sl@0
   631
sl@0
   632
  int2 temp;
sl@0
   633
sl@0
   634
/*
sl@0
   635
#    |== FOR i=1 to 8:
sl@0
   636
#    |    temp = abs( LARp[i] );
sl@0
   637
#    |    IF ( temp < 11059 ) THEN temp = temp << 1;
sl@0
   638
#    |         ELSE IF ( temp < 20070 ) THEN temp = add( temp, 11059 );
sl@0
   639
#    |              ELSE temp = add( ( temp >> 2 ), 26112 );
sl@0
   640
#    |    rp[i] = temp;
sl@0
   641
#    |    IF ( LARp[i] < 0 ) THEN rp[i] = sub( 0, rp[i] );
sl@0
   642
#    |== NEXT i:
sl@0
   643
*/
sl@0
   644
  for (i=1; i <= 8; i++) {
sl@0
   645
	int j = i-1;
sl@0
   646
    temp = abs_s( LARp[j] );
sl@0
   647
    if ( sub( temp, 11059 ) < 0 )
sl@0
   648
      temp = shl( temp, 1 );
sl@0
   649
    else if ( sub( temp, 20070 ) < 0 )
sl@0
   650
      temp = add( temp, 11059 );
sl@0
   651
    else
sl@0
   652
      temp = add( shr( temp, 2 ), 26112 );
sl@0
   653
sl@0
   654
    if ( LARp[j] < 0 )
sl@0
   655
      rp[j] = negate( temp );
sl@0
   656
    else
sl@0
   657
      rp[j] = temp;
sl@0
   658
  }
sl@0
   659
}
sl@0
   660
sl@0
   661
sl@0
   662
/*
sl@0
   663
#  4.2.10. Short term analysis filtering
sl@0
   664
#
sl@0
   665
#  This procedure computes the short term residual d[..] to be fed
sl@0
   666
#  to the RPE-LTP loop from s[..] signal and from the local rp[..]
sl@0
   667
#  array (quantized reflection coefficients). As the call of this
sl@0
   668
#  procedure can be done in many ways (see the interpolation of the LAR
sl@0
   669
#  coefficients), it is assumed that the computation begins with index
sl@0
   670
#  k_start (for arrays d[..] and s[..]) and stops with index k_end
sl@0
   671
#  (k_start and k_end are defined in 4.2.9.1): This procedure also need
sl@0
   672
#  to keep the array u[0..7] in memory for each call.
sl@0
   673
#
sl@0
   674
#  Keep the array u[0..7] in memory.
sl@0
   675
#  Initial value: u[0..7]=0;
sl@0
   676
*/
sl@0
   677
sl@0
   678
void invfil( CGSM610FR_Encoder* aEncoder, int2 d[], int2 s[], int2 rp[], int k_start, int k_end )
sl@0
   679
{
sl@0
   680
  //ALEX//extern int2 u[];
sl@0
   681
sl@0
   682
  int k, i;
sl@0
   683
sl@0
   684
  int2 temp;
sl@0
   685
  int2 sav;
sl@0
   686
  int2 di;
sl@0
   687
/*
sl@0
   688
#    |== FOR k=k_start to k_end:
sl@0
   689
#    |    di = s[k];
sl@0
   690
#    |    sav = di;
sl@0
   691
#    |==== FOR i=1 to 8:
sl@0
   692
#    |         temp = add( u[i], mult_r( rp[i], di ) );
sl@0
   693
#    |         di = add( di, mult_r( rp[i], u[i] ) );
sl@0
   694
#    |         u[i] = sav;
sl@0
   695
#    |         sav = temp;
sl@0
   696
#    |==== NEXT i:
sl@0
   697
#    |    d[k] = di;
sl@0
   698
#    |== NEXT k:
sl@0
   699
*/
sl@0
   700
  for ( k = k_start; k <= k_end; k++ ) {
sl@0
   701
    di = s[k];
sl@0
   702
    sav = di;
sl@0
   703
    for ( i = 1; i <= 8; i++ ) {
sl@0
   704
	  int j = i-1;
sl@0
   705
      temp = add( aEncoder->u[j], mult_r( rp[j], di ) );
sl@0
   706
      di = add( di, mult_r( rp[j], aEncoder->u[j] ) );
sl@0
   707
      aEncoder->u[j] = sav;
sl@0
   708
      sav = temp;
sl@0
   709
    }
sl@0
   710
    d[k] = di;
sl@0
   711
  }
sl@0
   712
sl@0
   713
}
sl@0
   714
sl@0
   715
sl@0
   716
/*
sl@0
   717
#  4.2.11. Calculation of the LTP parameters
sl@0
   718
#
sl@0
   719
#  This procedure computes the LTP gain (bc) and the LTP lag (Nc) for
sl@0
   720
#  the long term analysis filter. This is deone by calculating a maximum
sl@0
   721
#  of the cross-correlation function between the current sub-segment
sl@0
   722
#  short term residual signal d[0..39] (output of the short term 
sl@0
   723
#  analysis filter; for each sub-segment of the RPE-LTP analysis) and the
sl@0
   724
#  previous reconstructed short term residual signal dp[-120..-1]. A
sl@0
   725
#  dynamic scaling must be performed to avoid overflow.
sl@0
   726
# 
sl@0
   727
#  Initial value: dp[-120..-1]=0;
sl@0
   728
*/
sl@0
   729
sl@0
   730
void ltpcomp( CGSM610FR_Encoder* aEncoder, int2 *Nc, int2 *bc, int2 d[], int k_start )
sl@0
   731
{
sl@0
   732
  int k, i;
sl@0
   733
sl@0
   734
  int2 lambda;
sl@0
   735
  int2 temp;
sl@0
   736
  int2 scal;
sl@0
   737
  int2 dmax;
sl@0
   738
  int4 L_max;
sl@0
   739
  int2 wt[40]; /* scaled residual, original cannot be destroyed */
sl@0
   740
  int4 L_result;
sl@0
   741
  int4 L_power;
sl@0
   742
  int2 R;
sl@0
   743
  int2 S;
sl@0
   744
/*
sl@0
   745
# Search of optimum scaling of d[kstart+0..39]
sl@0
   746
#    dmax = 0;
sl@0
   747
#    |== FOR k=0 to 39:
sl@0
   748
#    |    temp = abs( d[k] );
sl@0
   749
#    |    IF ( temp > dmax ) THEN dmax = temp;
sl@0
   750
#    |== NEXT k:
sl@0
   751
*/
sl@0
   752
  dmax = 0;
sl@0
   753
  for (k=0; k <= 39; k++) {
sl@0
   754
    temp = abs_s( d[k+k_start] );
sl@0
   755
    if ( sub( temp, dmax ) > 0 )
sl@0
   756
      dmax = temp;
sl@0
   757
  }
sl@0
   758
/*
sl@0
   759
#    temp = 0;
sl@0
   760
#    IF ( dmax == 0 ) THEN scal = 0;
sl@0
   761
#         ELSE temp = norm( (long)dmax << 16 );
sl@0
   762
#    IF ( temp > 6 ) THEN scal = 0;
sl@0
   763
#         ELSE scal = sub( 6, temp );
sl@0
   764
*/  
sl@0
   765
  temp = 0;
sl@0
   766
  if ( dmax == 0 )
sl@0
   767
    scal = 0;
sl@0
   768
  else
sl@0
   769
    temp = norm_s( dmax );
sl@0
   770
sl@0
   771
  if ( sub( temp, 6 ) > 0 )
sl@0
   772
    scal = 0;
sl@0
   773
  else
sl@0
   774
    scal = sub( 6, temp );  /* 0 <= scal <= 6 */
sl@0
   775
/*
sl@0
   776
# Initialization of a working array wt[0..39]
sl@0
   777
#    |== FOR k=0 to 39:
sl@0
   778
#    |    wt[k] = d[k] >> scal;
sl@0
   779
#    |== NEXT k:
sl@0
   780
*/
sl@0
   781
  for (k=0; k <= 39; k++)
sl@0
   782
    wt[k] = shr( d[k+k_start], scal ); /* scal >= 0 */
sl@0
   783
/*
sl@0
   784
# Search for the maximum of crosscorrelation and coding of the LTP lag.
sl@0
   785
#    L_max = 0;
sl@0
   786
#    Nc = 40;
sl@0
   787
# 
sl@0
   788
#    |== FOR lambda=40 to 120:
sl@0
   789
#    |    L_result = 0;
sl@0
   790
#    |==== FOR k=0 to 39:
sl@0
   791
#    |         L_temp = L_mult( wt[k], dp[k-lambda] );
sl@0
   792
#    |         L_result = L_add( L_temp, L_result );
sl@0
   793
#    |==== NEXT k:
sl@0
   794
#    |    IF ( L_result > L_max ) THEN
sl@0
   795
#    |                                  |    Nc = lambda;
sl@0
   796
#    |                                  |    L_max = L_result;
sl@0
   797
#    |== NEXT lambda:
sl@0
   798
*/
sl@0
   799
  L_max = 0; /* 32 bits maximum */
sl@0
   800
  *Nc = 40; /* index for the maximum of cross correlation */
sl@0
   801
  for ( lambda = 40; lambda <= 120; lambda++ ) {
sl@0
   802
    L_result = 0;
sl@0
   803
    for (k = 0; k <= 39; k++)
sl@0
   804
	  L_result = L_mac( L_result, wt[k], aEncoder->dp[k-lambda+120] );
sl@0
   805
  /* Borland C++ 3.1 error if -3 (386-instructions) are used.
sl@0
   806
  ** The code makes error (compared to (L_result > L_max)
sl@0
   807
  ** comparison. The problem disapears if the result of L_sub
sl@0
   808
  ** is stored to variable, e.g.
sl@0
   809
  **   if ( ( L_debug = L_sub( L_result, L_max ) ) > 0 ) {
sl@0
   810
  **
sl@0
   811
  ** Problem does not occur when -2 option (only 286
sl@0
   812
  ** instructions are used)
sl@0
   813
  **
sl@0
   814
  ** The problem exist e.g. with GSM full rate test seq01.ib
sl@0
   815
  */
sl@0
   816
    if ( L_sub( L_result, L_max ) > 0 ) {
sl@0
   817
	 *Nc = lambda;
sl@0
   818
	 L_max = L_result;
sl@0
   819
    }
sl@0
   820
  }
sl@0
   821
sl@0
   822
/*
sl@0
   823
# Re-scaling of L-max
sl@0
   824
#    L_max = L_max >> sub( 6, scal );
sl@0
   825
*/
sl@0
   826
  L_max = L_shr( L_max, sub( 6, scal ) );
sl@0
   827
/*
sl@0
   828
# Initialization of a working array wt[0..39]
sl@0
   829
#    |== FOR k=0 to 39:
sl@0
   830
#    |    wt[k] = dp[k-Nc] >> 3;
sl@0
   831
#    |== NEXT k:
sl@0
   832
*/
sl@0
   833
  for (k = 0; k <= 39; k++)
sl@0
   834
    wt[k] = shr( aEncoder->dp[k - *Nc + 120], 3 );
sl@0
   835
/*
sl@0
   836
# Compute the power of the reconstructed short term residual signal dp[..]
sl@0
   837
#    L_power = 0;
sl@0
   838
#    |== FOR k=0 to 39:
sl@0
   839
#    |    L_temp = L_mult( wt[k], wt[k] );
sl@0
   840
#    |    L_power = L_add( L_temp, L_power );
sl@0
   841
#    |== NEXT k:
sl@0
   842
*/
sl@0
   843
  L_power = 0;
sl@0
   844
  for ( k = 0; k <= 39; k++ )
sl@0
   845
    L_power = L_mac( L_power, wt[k], wt[k] );
sl@0
   846
/*
sl@0
   847
# Normalization of L_max  and L_power
sl@0
   848
#    IF ( L_max <= 0 ) THEN
sl@0
   849
#                             | bc = 0;
sl@0
   850
#                             | EXIT; /cont. with 4.2.12/
sl@0
   851
*/
sl@0
   852
  if ( L_max <= 0 ) {
sl@0
   853
    *bc = 0;
sl@0
   854
    return;
sl@0
   855
  }
sl@0
   856
/*
sl@0
   857
#    IF ( L_max >= L_power ) THEN
sl@0
   858
#                             | bc = 3;
sl@0
   859
#                             | EXIT; /cont. with 4.2.12/
sl@0
   860
*/
sl@0
   861
  if ( L_sub( L_max, L_power ) >= 0 ) {
sl@0
   862
    *bc = 3;
sl@0
   863
    return;
sl@0
   864
  }
sl@0
   865
/*
sl@0
   866
#    temp = norm( L_power );
sl@0
   867
#    R = ( L_max << temp ) >> 16 );
sl@0
   868
#    S = ( L_power << temp ) >> 16 );
sl@0
   869
*/
sl@0
   870
  temp = norm_l( L_power );
sl@0
   871
  R = extract_h( L_shl( L_max, temp ) );
sl@0
   872
  S = extract_h( L_shl( L_power, temp ) );
sl@0
   873
/*
sl@0
   874
# Coding of the LTP gain
sl@0
   875
#
sl@0
   876
# Table 4.3a must be used to obtain the level DLB[i] for the
sl@0
   877
# quantization of the LTP gain b to get the coded version bc.
sl@0
   878
#
sl@0
   879
#    |== FOR bc=0 to 2:
sl@0
   880
#    |    IF ( R <= mult( S, DLB[bc] ) ) THEN EXIT; /cont. with 4.2.12/
sl@0
   881
#    |== NEXT bc:
sl@0
   882
#
sl@0
   883
#    bc = 3;
sl@0
   884
*/
sl@0
   885
  for ( i = 0; i <= 2; i++ ) {
sl@0
   886
    if ( sub( R, mult( S, DLB[i] ) ) <= 0 ) {
sl@0
   887
      *bc = int2 (i);
sl@0
   888
      return;
sl@0
   889
    }
sl@0
   890
  }
sl@0
   891
sl@0
   892
  *bc = 3;
sl@0
   893
sl@0
   894
}
sl@0
   895
sl@0
   896
sl@0
   897
/*
sl@0
   898
#  4.2.12. Long term analysis filtering
sl@0
   899
#
sl@0
   900
#  In this part, we have to decode the bc parameter to compute the
sl@0
   901
#  samples of the estimate dpp[0..39]. The decoding of bc needs the use
sl@0
   902
#  of table 4.3b. The long term residual signal e[0..39] is then
sl@0
   903
#  calculated to be fed to the RPE encoding section.
sl@0
   904
*/
sl@0
   905
sl@0
   906
void ltpfil( CGSM610FR_Encoder* aEncoder, int2 e[], int2 dpp[], int2 d[], int2 bc, int2 Nc, int k_start )
sl@0
   907
{
sl@0
   908
  int2 bp;
sl@0
   909
  int k;
sl@0
   910
sl@0
   911
/*
sl@0
   912
#    Decoding of the coded LTP gain.
sl@0
   913
#       bp = QLB[bc];
sl@0
   914
*/
sl@0
   915
	bp = QLB[bc];
sl@0
   916
/*
sl@0
   917
# Calculating the array e[0..39] and the array dpp[0..39]
sl@0
   918
#
sl@0
   919
#    |== FOR k=0 to 39:
sl@0
   920
#    |         dpp[k] = mult_r( bp, dp[k-Nc] );
sl@0
   921
#    |         e[k] = sub( d[k], dpp[k] );
sl@0
   922
#    |== NEXT k:
sl@0
   923
*/
sl@0
   924
  for ( k = 0; k <= 39; k++ ) {
sl@0
   925
    dpp[k] = mult_r( bp, aEncoder->dp[k - Nc + 120] );
sl@0
   926
    e[k] = sub( d[k+k_start], dpp[k] );
sl@0
   927
  }
sl@0
   928
}
sl@0
   929
sl@0
   930
sl@0
   931
/*
sl@0
   932
#  4.2.13. Weighting filter
sl@0
   933
#
sl@0
   934
#  The coefficients of teh weighting filter are stored in tables (see
sl@0
   935
#  table 4.4). The following scaling is used:
sl@0
   936
#
sl@0
   937
#  H[0..10] = integer( real_H[0..10]*8192 );
sl@0
   938
*/
sl@0
   939
sl@0
   940
void weight( int2 x[], int2 e[] )
sl@0
   941
{
sl@0
   942
  int k, i;
sl@0
   943
sl@0
   944
  int2 wt[50];
sl@0
   945
  int4 L_result;
sl@0
   946
/*
sl@0
   947
# Initialization of a temporary working array wt[0..49]
sl@0
   948
#    |== FOR k=0 to 4:
sl@0
   949
#    |    wt[k] = 0;
sl@0
   950
#    |== NEXT k:
sl@0
   951
#
sl@0
   952
#    |== FOR k=5 to 44:
sl@0
   953
#    |    wt[k] = e[k-5];
sl@0
   954
#    |== NEXT k:
sl@0
   955
#
sl@0
   956
#    |== FOR k=45 to 49:
sl@0
   957
#    |    wt[k] = 0;
sl@0
   958
#    |== NEXT k:
sl@0
   959
*/
sl@0
   960
  for ( k = 0; k <= 4; k++ ) 
sl@0
   961
    wt[k] = 0;
sl@0
   962
     
sl@0
   963
  for ( k = 5; k <= 44; k++ ) 
sl@0
   964
    wt[k] = e[k-5];
sl@0
   965
     
sl@0
   966
  for ( k = 45; k <= 49; k++ ) 
sl@0
   967
    wt[k] = 0;
sl@0
   968
/*
sl@0
   969
# Compute the signal x[0..39]
sl@0
   970
#    |== FOR k=0 to 39:
sl@0
   971
#    |    L_result = 8192;
sl@0
   972
#    |==== FOR i=0 to 10:
sl@0
   973
#    |         L_temp = L_mult( wt[k+i], H[i] );
sl@0
   974
#    |         L_result = L_add( L_result, L_temp );
sl@0
   975
#    |==== NEXT i:
sl@0
   976
#    |    L_result = L_add( L_result, L_result ); /scaling L_result (x2)/
sl@0
   977
#    |    L_result = L_add( L_result, L_result ); /scaling L_result (x4)/
sl@0
   978
#    |    x[k] = (int)( L_result >> 16 );
sl@0
   979
#    |== NEXT k:
sl@0
   980
*/
sl@0
   981
  for ( k = 0; k <= 39; k++ ) {
sl@0
   982
    L_result = L_deposit_l( 8192 );
sl@0
   983
    for ( i = 0; i <= 10; i++ )
sl@0
   984
      L_result = L_mac( L_result, wt[k+i], H[i] );
sl@0
   985
sl@0
   986
    /* scaling L_result (x4) and extract: scaling possible with new shift
sl@0
   987
     * because saturation is added L_shl
sl@0
   988
     *
sl@0
   989
     * L_result = L_add( L_result, L_result );
sl@0
   990
     * L_result = L_add( L_result, L_result );
sl@0
   991
     * x[k] = extract_h( L_result ); 
sl@0
   992
     @ Scaling can be done with L_shift because now shift has saturation
sl@0
   993
     */
sl@0
   994
sl@0
   995
    x[k] = extract_h( L_shl( L_result, 2 ) );
sl@0
   996
  }
sl@0
   997
}
sl@0
   998
sl@0
   999
sl@0
  1000
/*
sl@0
  1001
#  4.2.14. RPE grid selection
sl@0
  1002
#
sl@0
  1003
#  The signal x[0..39] is used to select the RPE grid which is
sl@0
  1004
#  represented by Mc.
sl@0
  1005
*/
sl@0
  1006
sl@0
  1007
int2 gridsel( int2 xM[], int2 x[] )
sl@0
  1008
{
sl@0
  1009
  int i, k;
sl@0
  1010
sl@0
  1011
  int2 temp1;
sl@0
  1012
  int4 L_EM;
sl@0
  1013
  int4 L_result;
sl@0
  1014
  int2 Mc;
sl@0
  1015
/*
sl@0
  1016
#    EM = 0;
sl@0
  1017
#    Mc = 0;
sl@0
  1018
*/
sl@0
  1019
  L_EM = 0;
sl@0
  1020
  Mc = 0;
sl@0
  1021
/*
sl@0
  1022
#    |== FOR m=0 to 3:
sl@0
  1023
#    |    L_result = 0;
sl@0
  1024
#    |==== FOR k=0 to 12:
sl@0
  1025
#    |         temp1 = x[i+(3*k)] >> 2;
sl@0
  1026
#    |         L_temp = L_mult( temp1, temp1 );
sl@0
  1027
#    |         L_result = L_add( L_temp, L_result );
sl@0
  1028
#    |==== NEXT i:
sl@0
  1029
#    |    IF ( L_result > L_max ) THEN
sl@0
  1030
#    |                                  |    Mc = m;
sl@0
  1031
#    |                                  |    EM = L_result;
sl@0
  1032
#    |== NEXT m:
sl@0
  1033
*/  
sl@0
  1034
  for ( i = 0; i <= 3; i++ ) {
sl@0
  1035
    L_result = 0;
sl@0
  1036
    for ( k = 0; k <= 12; k++ ) {
sl@0
  1037
      temp1 = shr( x[i+(3*k)], 2 );
sl@0
  1038
      L_result = L_mac( L_result, temp1, temp1 );
sl@0
  1039
    }
sl@0
  1040
    if ( L_sub( L_result, L_EM ) > 0 ) {
sl@0
  1041
      Mc = int2 (i);
sl@0
  1042
      L_EM = L_result;
sl@0
  1043
    }
sl@0
  1044
  }
sl@0
  1045
/*
sl@0
  1046
# Down-sampling by factor 3 to get the selected xM[0..12] RPE sequence
sl@0
  1047
#    |== FOR i=0 to 12:
sl@0
  1048
#    |    xM[k] = x[Mc+(3*i)];
sl@0
  1049
#    |== NEXT i:
sl@0
  1050
*/
sl@0
  1051
  for ( k = 0; k <= 12; k++ )
sl@0
  1052
    xM[k] = x[Mc+(3*k)];
sl@0
  1053
sl@0
  1054
  return Mc;
sl@0
  1055
}
sl@0
  1056
sl@0
  1057
sl@0
  1058
/*
sl@0
  1059
# Compute exponent and mantissa of the decoded version of xmaxc
sl@0
  1060
#
sl@0
  1061
# Part of APCM and (subrogram apcm() InvAPCM (iapcm())
sl@0
  1062
*/
sl@0
  1063
sl@0
  1064
void expman( int2 *Exp, int2 *mant, int2 xmaxc )
sl@0
  1065
{
sl@0
  1066
  int i;
sl@0
  1067
/*
sl@0
  1068
# Compute exponent and mantissa of the decoded version of xmaxc.
sl@0
  1069
#
sl@0
  1070
#    exp = 0;
sl@0
  1071
#    IF ( xmaxc > 15 ) THEN exp = sub( ( xmaxc >> 3 ), 1 );
sl@0
  1072
#    mant = sub( xmaxc, ( exp << 3 ) );
sl@0
  1073
*/
sl@0
  1074
  *Exp = 0;
sl@0
  1075
  if ( sub( xmaxc, 15 ) > 0 )
sl@0
  1076
    *Exp = sub( shr( xmaxc, 3 ), 1 );
sl@0
  1077
  
sl@0
  1078
  *mant = sub( xmaxc, shl( *Exp, 3 ) );
sl@0
  1079
/*
sl@0
  1080
# Normalize mantissa 0 <= mant <= 7.
sl@0
  1081
#    IF ( mant == 0 ) THEN    |    exp = -4;
sl@0
  1082
#                             |    mant = 15 ;
sl@0
  1083
#    ELSE | itest = 0;
sl@0
  1084
#         |== FOR i=0 to 2:
sl@0
  1085
#         |    IF ( mant > 7 ) THEN itest = 1;
sl@0
  1086
#         |    IF ( itest == 0 ) THEN mant = add( ( mant << 1 ), 1 );
sl@0
  1087
#         |    IF ( itest == 0 ) THEN exp = sub( exp, 1 );
sl@0
  1088
#         |== NEXT i:
sl@0
  1089
*/
sl@0
  1090
  if ( *mant == 0 ) {
sl@0
  1091
    *Exp = -4;
sl@0
  1092
    *mant = 15 ;
sl@0
  1093
  }
sl@0
  1094
  else {
sl@0
  1095
    for ( i = 0; i <= 2; i++ ) {
sl@0
  1096
      if ( sub( *mant, 7 ) > 0 )
sl@0
  1097
	break;
sl@0
  1098
      else {
sl@0
  1099
	*mant = add( shl( *mant, 1 ), 1 );
sl@0
  1100
	*Exp = sub( *Exp, 1 );
sl@0
  1101
      }
sl@0
  1102
    }
sl@0
  1103
  }
sl@0
  1104
/*
sl@0
  1105
#    mant = sub( mant, 8 );
sl@0
  1106
*/
sl@0
  1107
  *mant = sub( *mant, 8 );
sl@0
  1108
}
sl@0
  1109
sl@0
  1110
sl@0
  1111
int2 quantize_xmax( int2 xmax )
sl@0
  1112
{
sl@0
  1113
  int i;
sl@0
  1114
sl@0
  1115
  int2 Exp;
sl@0
  1116
  int2 temp;
sl@0
  1117
  int2 itest;
sl@0
  1118
/*
sl@0
  1119
# Quantizing and coding of xmax to get xmaxc.
sl@0
  1120
#    exp = 0;
sl@0
  1121
#    temp = xmax >> 9;
sl@0
  1122
#    itest = 0;
sl@0
  1123
#    |== FOR i=0 to 5:
sl@0
  1124
#    |    IF ( temp <= 0 ) THEN itest = 1;
sl@0
  1125
#    |    temp = temp >> 1;
sl@0
  1126
#    |    IF ( itest == 0 ) THEN exp = add( exp, 1 )  ;
sl@0
  1127
#    |== NEXT i:
sl@0
  1128
*/
sl@0
  1129
  Exp = 0;
sl@0
  1130
  temp = shr( xmax, 9 );
sl@0
  1131
  itest = 0;
sl@0
  1132
  for ( i = 0; i <= 5; i++ ) {
sl@0
  1133
    if ( temp <= 0 )
sl@0
  1134
      itest = 1;
sl@0
  1135
    temp = shr( temp, 1 );
sl@0
  1136
    if ( itest == 0 )
sl@0
  1137
      Exp = add( Exp, 1 )  ;
sl@0
  1138
  }
sl@0
  1139
sl@0
  1140
/*
sl@0
  1141
#    temp = add( exp, 5 );
sl@0
  1142
#    xmaxc = add( ( xmax >> temp ), ( exp << 3 ) );
sl@0
  1143
*/
sl@0
  1144
  temp = add( Exp, 5 );
sl@0
  1145
sl@0
  1146
  return ( add( shr( xmax, temp ), shl( Exp, 3 ) ) ); /* xmaxc */
sl@0
  1147
sl@0
  1148
}
sl@0
  1149
sl@0
  1150
sl@0
  1151
/*
sl@0
  1152
#  4.2.15. APCM quantization of the selected RPE sequence
sl@0
  1153
#
sl@0
  1154
#  Keep in memory exp and mant for the following inverse APCM quantizer.
sl@0
  1155
*
sl@0
  1156
* return unquantzed xmax for SID computation
sl@0
  1157
*/
sl@0
  1158
sl@0
  1159
int2 apcm( int2 *xmaxc, int2 xM[], int2 xMc[], int2 *Exp, int2 *mant )
sl@0
  1160
{
sl@0
  1161
  int k;
sl@0
  1162
sl@0
  1163
  int2 temp;
sl@0
  1164
  int2 temp1;
sl@0
  1165
  int2 temp2;
sl@0
  1166
  int2 temp3;
sl@0
  1167
  int2 xmax;
sl@0
  1168
/*
sl@0
  1169
# Find the maximum absolute value of xM[0..12].
sl@0
  1170
#    xmax = 0;
sl@0
  1171
#    |== FOR k=0 to 12:
sl@0
  1172
#    |    temp = abs( xM[k] );
sl@0
  1173
#    |    IF ( temp > xmax ) THEN xmax = temp;
sl@0
  1174
#    |== NEXT i:
sl@0
  1175
*/
sl@0
  1176
  xmax = 0;
sl@0
  1177
  for ( k = 0; k <= 12; k++ ) {
sl@0
  1178
    temp = abs_s( xM[k] );
sl@0
  1179
     if ( sub( temp, xmax ) > 0 )
sl@0
  1180
       xmax = temp;
sl@0
  1181
  }
sl@0
  1182
sl@0
  1183
  /*
sl@0
  1184
   * quantization of xmax moved to function because it is used
sl@0
  1185
   * also in comfort noise generation
sl@0
  1186
   */
sl@0
  1187
  *xmaxc = quantize_xmax( xmax );
sl@0
  1188
sl@0
  1189
  expman( Exp, mant, *xmaxc ); /* compute exp. and mant. */
sl@0
  1190
/*
sl@0
  1191
# Quantizing and coding of the xM[0..12] RPE sequence to get the xMc[0..12]
sl@0
  1192
#
sl@0
  1193
# This computation uses the fact that the decoded version of xmaxc can
sl@0
  1194
# be calculated by using the exponent and mantissa part of xmaxc
sl@0
  1195
# (logarithmic table).
sl@0
  1196
#
sl@0
  1197
# So, this method avoids any division and uses only scaling of the RPE
sl@0
  1198
# samples by a function of the exponent. A direct multiplication by the
sl@0
  1199
# inverse of the mantissa (NRFAC[0..7] found in table 4.5) gives the 3
sl@0
  1200
# bit coded version xMc[0..12} of the RPE samples.
sl@0
  1201
#
sl@0
  1202
# Direct computation of xMc[0..12] using table 4.5.
sl@0
  1203
#    temp1 = sub( 6, exp );   /normalization by the exponent/
sl@0
  1204
#    temp2 = NRFAC[mant];     /see table 4.5 (inverse mantissa)/
sl@0
  1205
#    |== FOR k=0 to 12:
sl@0
  1206
#    |    xM[k] = xM[k] << temp1;
sl@0
  1207
#    |    xM[k] = mult( xM[k], temp2 );
sl@0
  1208
#    |    xMc[k] = add( ( xM[k] >> 12 ), 4 );     / See note below/
sl@0
  1209
#    |== NEXT i:
sl@0
  1210
#
sl@0
  1211
# NOTE: This equation is used to make all the xMx[i] positive.
sl@0
  1212
*/
sl@0
  1213
  temp1 = sub( 6, *Exp );
sl@0
  1214
  temp2 = NRFAC[*mant];
sl@0
  1215
sl@0
  1216
  for ( k = 0; k <= 12; k++ )  {
sl@0
  1217
    temp3 = shl( xM[k], temp1 );
sl@0
  1218
    temp3 = mult( temp3, temp2 );
sl@0
  1219
    xMc[k] = add( shr( temp3, 12 ), 4 );
sl@0
  1220
  }
sl@0
  1221
sl@0
  1222
  return xmax;
sl@0
  1223
}
sl@0
  1224
sl@0
  1225
/*
sl@0
  1226
#  4.2.16. APCM inverse quantization
sl@0
  1227
#
sl@0
  1228
#  This part is for decoding the RPE sequence of coded xMc[0..12] samples
sl@0
  1229
#  to obtain the xMp[0..12] array. Table 4.6 is used to get the mantissa
sl@0
  1230
#  of xmaxc (FAC[0..7]).
sl@0
  1231
*/
sl@0
  1232
sl@0
  1233
void iapcm( int2 xMp[], int2 xMc[], int2 Exp, int2 mant )
sl@0
  1234
{
sl@0
  1235
  //ALEX//extern int2 FAC[];
sl@0
  1236
sl@0
  1237
  int k;
sl@0
  1238
sl@0
  1239
  int2 temp;
sl@0
  1240
  int2 temp1;
sl@0
  1241
  int2 temp2;
sl@0
  1242
  int2 temp3;
sl@0
  1243
/*
sl@0
  1244
#    temp1 = FAC[mant];       /See 4.2.15 for mant/
sl@0
  1245
#    temp2 = sub( 6, exp );   /See 4.2.15 for exp/
sl@0
  1246
#    temp3 = 1 << sub( temp2, 1 );
sl@0
  1247
*/
sl@0
  1248
  temp1 = FAC[mant];
sl@0
  1249
  temp2 = sub( 6, Exp );
sl@0
  1250
  temp3 = shl( 1, sub( temp2, 1 ) );
sl@0
  1251
/*
sl@0
  1252
#    |== FOR k=0 to 12:
sl@0
  1253
#    |    temp = sub( ( xMc[k] << 1 ), 7 );  /See note below/
sl@0
  1254
#    |    temp = temp << 12;
sl@0
  1255
#    |    temp = mult_r( temp1, temp );
sl@0
  1256
#    |    temp = add( temp, temp3 );
sl@0
  1257
#    |    xMp[k] = temp >> temp2;
sl@0
  1258
#    |== NEXT i:
sl@0
  1259
#
sl@0
  1260
# NOTE: This subtraction is used to restore the sign of xMc[i].
sl@0
  1261
*/
sl@0
  1262
  for ( k = 0; k <= 12; k++ ) {
sl@0
  1263
    temp = sub( shl( xMc[k], 1 ), 7 );
sl@0
  1264
    temp = shl( temp, 12 );
sl@0
  1265
    temp = mult_r( temp1, temp );
sl@0
  1266
    temp = add( temp, temp3 );
sl@0
  1267
    xMp[k] = shr( temp, temp2 );
sl@0
  1268
  }
sl@0
  1269
}
sl@0
  1270
sl@0
  1271
/*
sl@0
  1272
#  4.2.17. RPE grid positioning
sl@0
  1273
#
sl@0
  1274
#  This procedure computes the reconstructed long term residual signal
sl@0
  1275
#  ep[0..39] for the LTP analysis filter. The inputs are the Mc which is
sl@0
  1276
#  the grid position selection and the xMp[0..12] decoded RPE samples
sl@0
  1277
#  which are upsampled by factor of 3 by inserting zero values.
sl@0
  1278
*/
sl@0
  1279
sl@0
  1280
void gridpos( int2 ep[], int2 xMp[], int2 Mc )
sl@0
  1281
{
sl@0
  1282
  int k;
sl@0
  1283
/*
sl@0
  1284
#    |== FOR k=0 to 39:
sl@0
  1285
#    |    ep[k] = 0;
sl@0
  1286
#    |== NEXT k:
sl@0
  1287
*/
sl@0
  1288
  for ( k = 0; k <= 39; k++ ) 
sl@0
  1289
    ep[k] = 0;
sl@0
  1290
/*
sl@0
  1291
#    |== FOR i=0 to 12:
sl@0
  1292
#    |    ep[Mc + (3*k)] = xMp[k];
sl@0
  1293
#    |== NEXT i:
sl@0
  1294
*/
sl@0
  1295
  for ( k = 0; k <= 12; k++ ) 
sl@0
  1296
    ep[Mc + (3*k)] = xMp[k];
sl@0
  1297
}
sl@0
  1298
sl@0
  1299
sl@0
  1300
/*
sl@0
  1301
#  4.2.18. Update of the reconstructed short term residual signal dp[]
sl@0
  1302
#
sl@0
  1303
#  Keep the array dp[-120..-1] in memory for the next sub-segment.
sl@0
  1304
#  Initial value: dp[-120..-1]=0;
sl@0
  1305
*/
sl@0
  1306
sl@0
  1307
void ltpupd( CGSM610FR_Encoder* aEncoder, int2 dpp[], int2 ep[] )
sl@0
  1308
{
sl@0
  1309
  int i;
sl@0
  1310
/*
sl@0
  1311
#    |== FOR k=0 to 79:
sl@0
  1312
#    |    dp[-120+k] = dp[-80+k];
sl@0
  1313
#    |== NEXT k:
sl@0
  1314
*/
sl@0
  1315
  for (i = 0; i <= 79; i++) 
sl@0
  1316
    aEncoder->dp[-120+i+120] = aEncoder->dp[-80+i+120];
sl@0
  1317
/*
sl@0
  1318
#    |== FOR k=0 to 39:
sl@0
  1319
#    |    dp[-40+k] = add( ep[k], dpp[k] );
sl@0
  1320
#    |== NEXT k:
sl@0
  1321
*/
sl@0
  1322
  for (i = 0; i <= 39; i++) 
sl@0
  1323
    aEncoder->dp[-40+i+120] = add( ep[i], dpp[i] );
sl@0
  1324
}
sl@0
  1325
sl@0
  1326
sl@0
  1327
/*
sl@0
  1328
#  4.3.2. Long term synthesis filtering
sl@0
  1329
#
sl@0
  1330
#  Keep the nrp value for the next sub-segment.
sl@0
  1331
#  Initial value: nrp=40;
sl@0
  1332
#
sl@0
  1333
#  Keep the array drp[-120..-1] for the next sub-segment.
sl@0
  1334
#  Initial value: drp[-120..-1]=0;
sl@0
  1335
*/
sl@0
  1336
sl@0
  1337
void ltpsyn( CGSM610FR_Decoder* aDecoder, int2 erp[], int2 wt[], int2 bcr, int2 Ncr )
sl@0
  1338
{
sl@0
  1339
  int k, i;
sl@0
  1340
sl@0
  1341
  int2 drpp;
sl@0
  1342
  int2 Nr;
sl@0
  1343
  int2 brp;
sl@0
  1344
/*
sl@0
  1345
# Check the limits of Nr
sl@0
  1346
#    Nr = Ncr;
sl@0
  1347
#    IF ( Ncr < 40 ) THEN Nr = nrp;
sl@0
  1348
#    IF ( Ncr > 120 ) THEN Nr = nrp;
sl@0
  1349
#    nrp = Nr;
sl@0
  1350
*/
sl@0
  1351
  if ( sub( Ncr, 40 ) < 0 )
sl@0
  1352
    Nr = aDecoder->nrp;
sl@0
  1353
  else if ( sub( Ncr, 120 ) > 0 )
sl@0
  1354
    Nr = aDecoder->nrp;
sl@0
  1355
  else
sl@0
  1356
    Nr = Ncr;
sl@0
  1357
sl@0
  1358
  aDecoder->nrp = Nr;
sl@0
  1359
sl@0
  1360
/*
sl@0
  1361
# Decoding of the LTP gain bcr.
sl@0
  1362
#    brp = QLB[bcr];
sl@0
  1363
*/
sl@0
  1364
  brp = QLB[bcr];
sl@0
  1365
/*
sl@0
  1366
# Computation of the reconstructed short term residual signal drp[0..39].
sl@0
  1367
#    |== FOR k=0 to 39:
sl@0
  1368
#    |    drpp = mult_r( brp, drp[k-Nr] );
sl@0
  1369
#    |    drp[k+120] = add( erp[k], drpp );
sl@0
  1370
#    |== NEXT k:
sl@0
  1371
*/
sl@0
  1372
  for ( k = 0; k <= 39; k++ ) { 
sl@0
  1373
    drpp = mult_r( brp, aDecoder->drp[k-Nr+120] );
sl@0
  1374
    wt[k] = add( erp[k], drpp );
sl@0
  1375
  }
sl@0
  1376
/*
sl@0
  1377
# Update of the reconstructed short term residual signal drp[-1..-120]
sl@0
  1378
#    |== FOR k=0 to 119:
sl@0
  1379
#    |    drp[-120+k] = drp[-80+k];
sl@0
  1380
#    |== NEXT k:
sl@0
  1381
*/
sl@0
  1382
sl@0
  1383
  for ( i = 0; i < 80; i++ )
sl@0
  1384
    aDecoder->drp[i] = aDecoder->drp[40+i];
sl@0
  1385
sl@0
  1386
  for ( i = 0; i < 40; i++ )
sl@0
  1387
    aDecoder->drp[i+80] = wt[i];
sl@0
  1388
}
sl@0
  1389
sl@0
  1390
sl@0
  1391
/*
sl@0
  1392
#  4.3.4. Short term synthesis filtering section
sl@0
  1393
#
sl@0
  1394
#  This procedure uses the drp[0..39] signal and produces the sr[0..159]
sl@0
  1395
#  signal which is the output of the short term synthesis filter. For
sl@0
  1396
#  ease of explanation, a temporary array wt[0..159] is used.
sl@0
  1397
#
sl@0
  1398
#  Initialization of the array wt[0..159].
sl@0
  1399
#
sl@0
  1400
#  For the first sub-segment in a frame:
sl@0
  1401
#    |== FOR k=0 to 39:
sl@0
  1402
#    |    wt[k] = drp[k];
sl@0
  1403
#    |== NEXT k:
sl@0
  1404
#
sl@0
  1405
#  For the second sub-segment in a frame:
sl@0
  1406
#    |== FOR k=0 to 39:
sl@0
  1407
#    |    wt[40+k] = drp[k];
sl@0
  1408
#    |== NEXT k:
sl@0
  1409
#
sl@0
  1410
#  For the third sub-segment in a frame:
sl@0
  1411
#    |== FOR k=0 to 39:
sl@0
  1412
#    |    wt[80+k] = drp[k];
sl@0
  1413
#    |== NEXT k:
sl@0
  1414
#
sl@0
  1415
#  For the fourth sub-segment in a frame:
sl@0
  1416
#    |== FOR k=0 to 39:
sl@0
  1417
#    |    wt[120+k] = drp[k];
sl@0
  1418
#    |== NEXT k:
sl@0
  1419
#
sl@0
  1420
#  As the call of the short term synthesis filter procedure can be done
sl@0
  1421
#  in many ways (see the interpolation of the LAR coefficient), it is
sl@0
  1422
#  assumed that the computation begins with index k_start (for arrays
sl@0
  1423
#  wt[..] and sr[..]) and stops with index k_end (k_start and k_end are
sl@0
  1424
#  defined in 4.2.9.1). The procedure also needs to keep the array
sl@0
  1425
#  v[0..8] in memory between calls.
sl@0
  1426
#
sl@0
  1427
#  Keep the array v[0..8] in memory for the next call.
sl@0
  1428
#  Initial value: v[0..8]=0;
sl@0
  1429
*/
sl@0
  1430
sl@0
  1431
void synfil( CGSM610FR_Decoder* aDecoder, int2 sr[], int2 wt[], int2 rrp[], int k_start, int k_end )
sl@0
  1432
{
sl@0
  1433
  int k;
sl@0
  1434
  int i;
sl@0
  1435
sl@0
  1436
  int2 sri;
sl@0
  1437
/*
sl@0
  1438
#    |== FOR k=k_start to k_end:
sl@0
  1439
#    |    sri = wt[k];
sl@0
  1440
#    |==== FOR i=1 to 8:
sl@0
  1441
#    |         sri = sub( sri, mult_r( rrp[9-i], v[8-i] ) );
sl@0
  1442
#    |         v[9-i] = add( v[8-i], mult_r( rrp[9-i], sri ) ) ;
sl@0
  1443
#    |==== NEXT i:
sl@0
  1444
#    |    sr[k] = sri;
sl@0
  1445
#    |    v[0] = sri;
sl@0
  1446
#    |== NEXT k:
sl@0
  1447
*/
sl@0
  1448
  for ( k = k_start; k <= k_end; k++ ) {
sl@0
  1449
    sri = wt[k];
sl@0
  1450
    for ( i = 1; i <= 8; i++ ) {
sl@0
  1451
	  int j = i+1;
sl@0
  1452
      sri = sub( sri, mult_r( rrp[9-j], aDecoder->v[8-i] ) );
sl@0
  1453
      aDecoder->v[9-i] = add( aDecoder->v[8-i], mult_r( rrp[9-j], sri ) ) ;
sl@0
  1454
    }
sl@0
  1455
    sr[k] = sri;
sl@0
  1456
    aDecoder->v[0] = sri;
sl@0
  1457
  }
sl@0
  1458
sl@0
  1459
}
sl@0
  1460
sl@0
  1461
sl@0
  1462
/*
sl@0
  1463
** 4.3.5., 4.3.6., 4.3.7. Postprocessing
sl@0
  1464
**
sl@0
  1465
** Combined deemphasis, upscaling and truncation
sl@0
  1466
*/
sl@0
  1467
void postpr( CGSM610FR_Decoder* aDecoder, int2 srop[], int2 sr[] )
sl@0
  1468
{
sl@0
  1469
  int k;
sl@0
  1470
/*
sl@0
  1471
# 4.3.5. Deemphasis filtering
sl@0
  1472
#
sl@0
  1473
# Keep msr in memory for the next frame.
sl@0
  1474
# Initial value: msr=0;
sl@0
  1475
*/
sl@0
  1476
/*
sl@0
  1477
#    |== FOR k=0 to 159:
sl@0
  1478
#    |    temp = add( sr[k], mult_r( msr, 28180 ) );
sl@0
  1479
#    |    msr = temp;
sl@0
  1480
#    |    sro[k] = msr;
sl@0
  1481
#    |== NEXT k:
sl@0
  1482
*/
sl@0
  1483
/*
sl@0
  1484
# 4.3.6 Upscaling of the output signal
sl@0
  1485
*/
sl@0
  1486
/*
sl@0
  1487
#    |== FOR k=0 to 159:
sl@0
  1488
#    |    srop[k] = add( sro[k], sro[k] );
sl@0
  1489
#    |== NEXT k:
sl@0
  1490
*/
sl@0
  1491
/*
sl@0
  1492
# 4.3.7. Truncation of the output variable
sl@0
  1493
*/
sl@0
  1494
/*
sl@0
  1495
#    |== FOR k=0 to 159:
sl@0
  1496
#    |    srop[k] = srop[k] >> 3;
sl@0
  1497
#    |    srop[k] = srop[k] << 3;
sl@0
  1498
#    |== NEXT k:
sl@0
  1499
*/
sl@0
  1500
sl@0
  1501
  for ( k = 0; k <= 159; k++ ) {
sl@0
  1502
    aDecoder->msr = add( sr[k], mult_r( aDecoder->msr, 28180 ) );
sl@0
  1503
    srop[k] = int2 (shl( aDecoder->msr, 1 ) & 0xfff8);
sl@0
  1504
  }
sl@0
  1505
}
sl@0
  1506