5 Computational details of the RPE‑LTP codec
3GPP46.010Full rate speechRelease 17TranscodingTS
5.1 Data representation and arithmetic operations
Only two types of variables are used along the implementation of the RPE‑LTP algorithm in fixed point arithmetic. These two types are:
Integer on 16 bits;
Long integer on 32 bits.
This assumption simplifies the detailed description and allows the maximum reach of precision.
In different places of the recommendation, different scaling factors are used according to different operations. To help the reader in the comparison of corresponding floating point and fixed point values given in clause 3 and 4 comments of the format:
/* var = integer( real_var * scalefactor ) */
are used at several points of clause 5. var is the rounded fixed point representation of the floating point representation of var (real_var) using the given scaling factor.
In the description, input signal samples, coded parameters and output signal samples are represented by 16 bit words. At the receiving part it shall therefore be ensured that only valid bits (13 bits for samples signal and two to seven bits for coded parameters) are used. In verification tests, the testing system may introduce random bit at non valid places inside these samples (3 LSBs) or parameters (MSBs) to test this function. In the digital test sequences all non valid bits are set to 0.
The following part of this clause describes the required set of arithmetic operations to implement the RPE‑LTP algorithm in fixed point.
For arithmetics operations or variables with a long integer type (32 bit) a prefix L_ is used in order to distinguish them from the 16 bit variables or arithmetic operations.
All the names of the variables are identical to those of the functional description of the RPE‑LTP Codec (clause 3) but variables like x’, x” are respectively called:
x’ —–> xp
x”—–> xpp
in order to avoid any confusing notation.
NOTE: The x’, x" variables are examples but are not used within the following description.
The following notations are used in the arithmetic operations:
Square brackets ( [..] ) are used for arrays and when needed, the starting index and the ending index are put inside the bracket. For example x[0..159] means that x is an array of 160 words of 16 bits with beginning index 0 and ending index 159 and x[k] is an element of the array x[0..159].
All functions’ names are underlined. For example add( x, y) means that we perform the addition of x and y.
<< n: denotes a n‑bit arithmetic shift left operation (zero fill) on variables of type short or long; if n is less than 0, this operation becomes an arithmetic right shift of ‑n;
>> n: denotes a n‑bit arithmetic right shift operation (sign extension ) on variables of type short or long; if n is less than 0, this operation becomes an arithmetic left shift of ‑n (zero fill);
a > b: denotes the "greater than" condition;
a >= b: denotes the "greater than or equal" condition;
a < b: denotes the "less than" condition;
a <= b: denotes the "less than or equal" condition;
a == b: denotes the "equal to" condition.
The basic structure of the FOR‑NEXT loop is used in this description for loop computation; the declaration is:
|== FOR k= start to end:
| inner computation;
|== NEXT k:
Also the IF.. ELSE IF structure is used throughout this detailed description. The basic structure is:
IF (condition1) THEN statement1;
ELSE IF ( condition2) THEN statement2;
ELSE IF ( condition3) THEN statement3;
The word EXIT is used to exit immediately from a procedure.
The following arithmetic operations are defined:
add( var1, var2): performs the addition (var1+var2) with overflow control and saturation; the result is set at +32767 when overflow occurs or at ‑32768 when underflow occurs.
sub( var1, var2): performs the subtraction (var1‑var2) with overflow control and saturation; the result is set at +32767 when overflow occurs or at ‑32768 when underflow occurs.
mult( var1, var2): performs the multiplication of var1 by var2 and gives a 16 bits result which is scaled i.e.
mult(var1,var2 ) = (var1 times var2) >> 15 and mult(‑32768, ‑32768) = 32767
mult_r( var1, var2): same as mult but with rounding i.e. mult_r( var1, var2 ) = ( (var1 times var2) + 16384 ) >> 15 and mult_r( ‑32768, ‑32768 ) = 32767
abs( var1 ): absolute value of var1; abs(‑32768) = 32767
div( var1, var2): div produces a result which is the fractional integer division of var1 by var2; var1 and var2 shall be positive and var2 shall be greater or equal to var1; The result is positive (leading bit equal to 0) and truncated to 16 bits. if var1 == var2 then div( var1, var2 ) = 32767
L_mult(var1, var2): L_mult is a 32 bit result for the multiplication of var1 times var2 with a one bit shift left. L_mult( var1, var2 ) = ( var1 times var2 ) << 1. The condition L_mult (‑32768, ‑32768 ) does not occur in the algorithm.
L_add(L_var1, L_var2): 32 bits addition of two 32 bits variables (L_var1 + L_var2) with overflow control and saturation; the result is set at 2147483647 when overflow occurs and at ‑2147483648 when underflow occurs.
L_sub(L_var1,L_var2): 32 bits subtraction of two 32 bits variables (L_var1 ‑ L_var2) with overflow control and saturation; the result is set at 2147483647 when overflow occurs and at ‑2147483648 when underflow occurs.
norm( L_var1 ): norm produces the number of left shifts needed to normalize the 32 bits variable L_var1 for positive values on the interval with minimum of 1073741824 and maximum of 2147483647 and for negative values on the interval with minimum of ‑2147483648 and maximum of ‑1073741824; in order to normalize the result, the following operation shall be done: L_norm_var1 = L_var1 << norm(L_var1)
L_var2 = var1: deposit the 16 bits of var1 in the LSB 16 bits of L_var2 with sign extension.
var2 = L_var1: extract the 16 LSB bits of L_var1 to put in var2.
When a constant is used in an operation on 32 bits, it shall be first sign‑extended on 32 bits.
5.2 Fixed point implementation of the RPE‑LTP coder
The RPE‑LTP 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 (analysis) and some others for each of the four sub‑segments (40 samples).
In the following detailed description, procedure 5.2.0 to 5.2.10 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:
| LARc[1..8] : Coded LAR coefficients
|–> These parameters are calculated and sent once per frame.
Procedure 5.2.11 to 5.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:
| Nc : LTP lag;
| bc : Coded LTP gain;
| Mc : RPE grid selection;
| xmaxc : Coded maximum amplitude of the RPE sequence;
| xMc[0..12] : Codes of the normalized RPE samples;
|–> These parameters are calculated and sent four times per frame.
Pre‑processing clause
5.2.0 Scaling of the input variable
After A or -‑law (PCS 1900) to linear conversion (or directly from the A to D converter) the following scaling is assumed for input to the RPE‑LTP algorithm:
S.v.v.v.v.v.v.v.v.v.v.v.v.x.x.x ( 2’s complement format).
Where S is the sign bit, v a valid bit, and x a "don’t care" bit.
The original signal is called sop[..];
5.2.1 Downscaling of the input signal
|== FOR k=0 to 159:
| so[k] = sop[k] >> 3;
| so[k] = so[k] << 2;
|== NEXT k:
5.2.2 Offset compensation
This part implements a high‑pass filter and requires extended arithmetic precision for the recursive part of this filter.
The input of this procedure is the array so[0..159] and the output the array sof[0..159].
|== FOR k = 0 to 159:
| Compute the non-recursive part.
| s1 = sub( so[k], z1 );
| z1 = so[k];
| Compute the recursive part.
| L_s2 = s1;
| L_s2 = L_s2 << 15;
| Execution of a 31 by 16 bits multiplication.
| msp = L_z2 >> 15;
| lsp = L_sub( L_z2, ( msp << 15 ) );
| temp = mult_r( lsp, 32735 );
| L_s2 = L_add( L_s2, temp );
| L_z2 = L_add( L_mult( msp, 32735 ) >> 1, L_s2 );
| Compute sof[k] with rounding.
| sof[k] = L_add( L_z2, 16384 ) >> 15;
|== NEXT k:
Keep z1 and L_z2 in memory for the next frame.
Initial value: z1=0; L_z2=0;
5.2.3 Pre‑emphasis
|== FOR k=0 to 159:
| s[k] = add( sof[k], mult_r( mp, ‑28180 ) );
| mp = sof[k];
|== NEXT k:
Keep mp in memory for the next frame.
Initial value: mp=0;
LPC analysis clause
5.2.4 Autocorrelation
The goal is to compute the array L_ACF[k]. The signal s[i] shall be scaled in order to avoid an overflow situation.
Dynamic scaling of the array s[0..159].
Search for the maximum.
smax = 0;
|== FOR k = 0 to 159:
| temp = abs( s [k] );
| IF ( temp > smax ) THEN smax = temp;
|== NEXT k;
Computation of the scaling factor.
IF ( smax == 0 ) THEN scalauto = 0;
ELSE scalauto = sub( 4, norm( smax << 16 ) );
Scaling of the array s[0..159].
IF ( scalauto > 0 ) THEN
| temp = 16384 >> sub( scalauto,1);
|== FOR k = 0 to 159:
| s[k] = mult_r( s[k], temp);
|== NEXT k:
Compute the L_ACF[..].
|== FOR k=0 to 8:
| L_ACF[k] = 0;
|==== FOR i=k to 159:
| L_temp = L_mult( s[i], s[i-k] );
| L_ACF[k] = L_add( L_ACF[k], L_temp );
|==== NEXT i:
|== NEXT k:
Rescaling of the array s[0..159].
IF ( scalauto > 0 ) THEN
|== FOR k = 0 to 159:
| s[k] = s[k] << scalauto;
|== NEXT k:
5.2.5 Computation of the reflection coefficients
Schur recursion with 16 bits arithmetic.
IF( L_ACF[0] == 0 ) THEN
|== FOR i = 1 to 8:
| r[i] = 0;
|== NEXT i:
| EXIT; /continue with clause 5.2.6/
temp = norm( L_ACF[0] );
|== FOR k=0 to 8:
| ACF[k] = ( L_ACF[k] << temp ) >> 16;
|== NEXT k:
Initialize array P[..] and K[..] for the recursion.
|== FOR i=1 to 7:
| K[9-i] = ACF[i];
|== NEXT i:
|== FOR i=0 to 8:
| P[i] = ACF[i];
|== NEXT i:
Compute reflection coefficients.
|== FOR n=1 to 8:
| IF( P[0] < abs( P[1] ) ) THEN
| |== FOR i = n to 8:
| | r[i] = 0;
| |== NEXT i:
| | EXIT; /continue with
| | clause 5.2.6/
| r[n] = div( abs( P[1] ), P[0] );
| IF ( P[1] > 0 ) THEN r[n] = sub( 0, r[n] );
|
| IF ( n == 8 ) THEN EXIT; /continue with
clause 5.2‑6/
Schur recursion.
| P[0] = add( P[0], mult_r( P[1], r[n] ) );
|==== FOR m=1 to 8-n:
| P[m] = add( P[m+1], mult_r( K[9-m], r[n] ) );
| K[9-m] = add( K[9-m], mult_r( P[m+1], r[n] ) );
|==== NEXT m:
|
|== NEXT n:
NOTE: The following lines gives one correct implementation of the div(num, denum) arithmetic operation. Compute div which is the integer division of num by denum: with denum >= num > 0.
L_num = num;
L_denum = denum;
div =0;
|== FOR k = 0 to 14:
| div= div << 1;
| L_num = L_num << 1;
| IF ( L_num >= L_denum) THEN
| | L_num=L_sub(L_num, L_denum);
| | div = add( div ,1 );
|== NEXT k:
5.2.6 Transformation of reflection coefficients to Log.‑Area Ratios
The following scaling for r[..] and LAR[..] has been used:
/* r[..] = integer( real_r[..]*32768. ); ‑1. <= real_r <1. */
/* */
/* LAR[..] = integer( real_LAR[..]*16384. ); */
/* */
/* with ‑1.625 <= real_LAR <= 1.625 */
Computation of the LAR[1..8] from the r[1..8].
|== FOR i = 1 to 8:
| temp = abs( r[i] );
| IF ( temp < 22118 ) THEN temp = temp >> 1;
| ELSE IF ( temp < 31130 ) THEN
| temp= sub(temp, 11059);
| ELSE temp = sub( temp, 26112 ) << 2;
| LAR[i] = temp;
| IF ( r[i] < 0 ) THEN LAR[i] = sub( 0, LAR[i] );
|== NEXT i:
5.2.7 Quantization and coding of the Log.‑Area Ratios
This procedure needs four tables; the following equations give the optimum scaling for the constants:
/* A[1..8]= integer( real_A[1..8]*1024); 8 values (see table5.1)*/
/* */
/* B[1..8]= integer( real_B[1..8]*512); 8 values (see table5.1)*/
/* */
/* MAC[1..8]= maximum of the LARc[1..8]; 8 values (see table5.1)*/
/* */
/* MIC[1..8]= minimum of the LARc[1..8]; 8 values (see table5.1)*/
Computation for quantizing and coding the LAR[1..8].
|== FOR i =1 to 8:
| temp= mult( A[i], LAR[i] );
| temp= add( temp, B[i] );
| temp= add( temp, 256); for rounding
| LARc[i]= temp >> 9;
|
| Check IF LARc[i] lies between MIN and MAX
|
| IF ( LARc[i] > MAC[i] ) THEN LARc[i] = MAC[i];
| IF ( LARc[i] < MIC[i] ) THEN LARc[i] = MIC[i];
| LARc[i] = sub( LARc[i], MIC[i] ); /See note below/
|== NEXT i:
NOTE: The equation is used to make all the LARc[i] positive.
Short term analysis filtering clause
5.2.8 Decoding of the coded Log.‑Area Ratios
This procedure requires for efficient implementation two tables.
/* INVA[1..8]=integer((32768*8)/(real_A[1..8]); */
/* 8 values (table 5.2 ) */
/* MIC[1..8]=minimum value of the LARc[1..8]; */
/* 8 values (table 5.1) */
Compute the LARpp[1..8].
|== FOR i=1 to 8:
| temp1 = add( LARc[i], MIC[i] ) << 10; /See note below/
| temp2 = B[i] << 1;
| temp1 = sub( temp1, temp2);
| temp1 = mult_r( INVA[i], temp1);
| LARpp[i] = add( temp1, temp1);
|== NEXT i:
NOTE: The addition of MIC[i] is used to restore the sign of LARc[i].
5.2.9 Computation of the quantized reflection coefficients
Within each frame of 160 analysed speech samples the short term analysis and synthesis filters operate with four different sets of coefficients, derived from the previous set of decoded LARs(LARpp(j‑1)) and the actual set of decoded LARs (LARpp(j)).
5.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8]
For k_start = 0 to k_end = 12.
|==== FOR i= 1 to 8:
| LARp[i] = add((LARpp(j‑1)[i] >> 2),(LARpp(j)[i] >> 2));
| LARp[i] = add( LARp[i] , ( LARpp(j‑1)[i] >> 1 ) );
|==== NEXT i:
For k_start = 13 to k_end = 26.
|==== FOR i= 1 to 8:
| LARp[i] = add((LARpp(j‑1)[i] >> 1),(LARpp(j)[i] >> 1 ));
|==== NEXT i:
For k_start = 27 to k_end = 39.
|==== FOR i= 1 to 8:
| LARp[i] = add((LARpp(j‑1)[i] >> 2),(LARpp(j)[i] >> 2 ));
| LARp[i] = add( LARp[i] , ( LARpp(j)[i] >> 1 ) );
|==== NEXT i:
For k_start = 40 to k_end = 159.
|==== FOR i= 1 to 8:
| LARp[i] = LARpp(j)[i];
|==== NEXT i:
Initial value: LARpp(j‑1)[1..8]=0;
5.2.9.2 Computation of the rp[1..8] from the interpolated LARp[1..8]
The input of this procedure is the interpolated LARp[1..8] array. The reflection coefficients, rp[i], are used in the analysis filter and in the synthesis filter.
|== FOR i=1 to 8:
| temp = abs( LARp[i] );
| IF ( temp < 11059 ) THEN temp = temp << 1;
| ELSE IF (temp < 20070) THEN
| temp = add(temp, 11059);
| ELSE temp = add( (temp >> 2), 26112 );
| rp[i] = temp;
| IF ( LARp[i] < 0 ) THEN rp[i] = sub( 0, rp[i] );
|== NEXT i:
5.2.10 Short term analysis filtering
This procedure computes the short term residual signal d[..] to be fed to the RPE‑LTP loop from the s[..] signal and from the local rp[..] array (quantized reflection coefficients). As the call of this procedure can be done in many ways (see the interpolation of the LAR coefficient), it is assumed that the computation begins with index k_start (for arrays d[..] and s[..]) and stops with index k_end (k_start and k_end are defined in 5.2.9.1). This procedure also needs to keep the array u[0..7] in memory for each call.
|== FOR k = k_start to k_end:
| di = s[k]
| sav = di;
|==== FOR i = 1 to 8:
| temp = add( u[i‑1], mult_r( rp[i], di ) );
| di = add( di, mult_r( rp[i], u[i‑1] ) );
| u[i‑1] = sav;
| sav = temp;
|==== NEXT i:
| d[k] = di;
|== NEXT k:
Keep the array u[0..7] in memory.
Initial value: u[0..7]=0;
Long Term Predictor (LTP) clause
5.2.11 Calculation of the LTP parameters
This procedure computes the LTP gain (bc) and the LTP lag (Nc) for the long term analysis filter. This is done by calculating a maximum of the cross‑correlation function between the current sub‑segment short term residual signal d[0..39] (output of the short term analysis filter; for simplification the index of this array begins at 0 and ends at 39 for each sub‑segment of the RPE‑LTP analysis) and the previous reconstructed short term residual signal dp[‑120..‑1]. A dynamic scaling shall be performed to avoid overflow.
Search of the optimum scaling of d[0..39].
dmax = 0;
|== FOR k = 0 to 39:
| temp = abs( d[k] );
| IF ( temp > dmax ) THEN dmax = temp;
|== NEXT k:
temp = 0;
IF ( dmax == 0 ) THEN scal = 0;
ELSE temp = norm( dmax << 16 );
IF ( temp > 6 ) THEN scal = 0;
ELSE scal = sub( 6, temp );
Initialization of a working array wt[0..39].
|== FOR k = 0 to 39:
| wt[k] = d[k] >> scal;
|== NEXT k:
Search for the maximum cross‑correlation and coding of the LTP lag.
L_max = 0;
Nc = 40; (index for the maximum cross-correlation)
|== FOR lambda = 40 to 120:
| L_result = 0;
|==== FOR k = 0 to 39:
| L_temp = L_mult( wt[k], dp[k-lambda] );
| L_result = L_add( L_temp, L_result );
|==== NEXT k:
| IF ( L_result > L_max) THEN
| | Nc = lambda;
| | L_max = L_result ;
|== NEXT lambda:
Rescaling of L_max.
L_max = L_max >> ( sub( 6, scal ) );
Initialization of a working array wt[0..39].
|== FOR k = 0 to 39:
| wt[k] = dp[k-Nc] >> 3;
|== NEXT k:
Compute the power of the reconstructed short term residual signal dp[..].
L_power = 0;
|== FOR k =0 to 39:
| L_temp = L_mult( wt[k], wt[k] );
| L_power = L_add( L_temp, L_power );
|== NEXT k:
Normalization of L_max and L_power.
IF ( L_max <= 0 ) THEN
| bc = 0;
| EXIT; /cont. with 5.2.12/
IF ( L_max >= L_power ) THEN
| bc = 3;
| EXIT; /cont. with 5.2.12/
temp = norm( L_power );
R = ( L_max << temp ) >> 16;
S = ( L_power << temp ) >> 16;
Coding of the LTP gain.
Table 5.3a shall be used to obtain the level DLB[i] for the quantization of the LTP gain b to get the coded version bc.
|== FOR bc = 0 to 2:
| IF (R <= mult(S, DLB[bc])) THEN EXIT; /cont. with
5.2.12/
|== NEXT bc;
bc = 3;
Initial value: dp[‑120..‑1]=0;
5.2.12 Long term analysis filtering
In this part, we have to decode the bc parameter to compute the samples of the estimate dpp[0..39]. The decoding of bc needs the use of table 5.3b. The long term residual signal e[0..39] is then calculated to be fed to the RPE encoding clause.
Decoding of the coded LTP gain.
bp = QLB[bc];
Calculating the array e[0..39] and the array dpp[0..39].
|== FOR k = 0 to 39:
| dpp[k] = mult_r( bp, dp[k-Nc] );
| e[k] = sub( d[k], dpp[k] );
|== NEXT k:
RPE encoding clause
5.2.13 Weighting filter
The coefficients of the weighting filter are stored in a table (see table 5.4). The following scaling is used:
/* H[0..10] = integer( real_H[0..10]*8192 ); */
Initialization of a temporary working array wt[0..49].
|== FOR k= 0 to 4:
| wt[k] = 0;
|== NEXT k:
|== FOR k = 5 to 44:
| wt[k] = e[k‑5];
|== NEXT k:
|== FOR k= 45 to 49:
| wt[k] = 0;
|== NEXT k:
Compute the signal x[0..39].
|== FOR k= 0 to 39:
| L_result = 8192; /rounding of the output
of the filter/
|==== FOR i = 0 to 10:
| L_temp = L_mult( wt[k+i], H[i] );
| L_result = L_add( L_result, L_temp );
|==== NEXT i:
| L_result = L_add(L_result,L_result); /scaling (x2)/
| L_result = L_add(L_result,L_result); /scaling (x4)/
| x[k] = L_result >> 16;
|== NEXT k:
5.2.14 RPE grid selection
The signal x[0..39] is used to select the RPE grid which is represented by Mc.
EM =0;
Mc = 0;
|== FOR m = 0 to 3:
| L_result = 0;
|==== FOR i = 0 to 12:
| temp1 = x[m+(3*i)] >> 2;
| L_temp = L_mult( temp1, temp1 );
| L_result = L_add( L_temp, L_result );
|==== NEXT i:
| IF ( L_result > EM) THEN
| | Mc = m;
| | EM = L_result;
|== NEXT m:
Down‑sampling by a factor 3 to get the selected xM[0..12] RPE sequence.
|== FOR i = 0 to 12:
| xM[i] = x[Mc +(3*i)];
|== NEXT i:
5.2.15 APCM quantization of the selected RPE sequence
Find the maximum absolute value xmax of xM[0..12].
xmax = 0;
|== FOR i = 0 to 12:
| temp = abs( xM[i] ) ;
| IF ( temp > xmax ) THEN xmax = temp;
|== NEXT i:
Quantizing and coding of xmax to get xmaxc.
exp = 0;
temp = xmax >> 9;
itest = 0;
|== FOR i = 0 to 5:
| IF ( temp <= 0 ) THEN itest = 1;
| temp = temp >> 1;
| IF ( itest == 0 ) THEN exp = add( exp, 1 ) ;
|== NEXT i:
temp = add( exp, 5 ) ;
xmaxc = add( ( xmax >> temp ), ( exp << 3 ) ) ;
Quantizing and coding of the xM[0..12] RPE sequence to get the xMc[0..12].
This computation uses the fact that the decoded version of xmaxc can be calculated by using the exponent and the mantissa part of xmaxc (logarithmic table).
So, this method avoids any division and uses only a scaling of the RPE samples by a function of the exponent. A direct multiplication by the inverse of the mantissa (NRFAC[0..7] found in table 5.5) gives the 3 bit coded version xMc[0..12] of the RPE samples.
Compute exponent and mantissa of the decoded version of xmaxc.
exp = 0 ;
IF ( xmaxc > 15 ) THEN exp = sub( ( xmaxc >> 3 ), 1 ) ;
mant = sub( xmaxc , ( exp << 3 ) );
Normalize mantissa 0 <= mant <= 7.
IF ( mant == 0 ) THEN | exp = ‑4;
| mant = 15;
ELSE | itest = 0;
|== FOR i = 0 to 2:
| IF ( mant > 7 ) THEN itest = 1;
| IF (itest == 0) THEN mant = add((mant << 1),1);
| IF ( itest == 0 ) THEN exp = sub( exp, 1 );
|== NEXT i:
mant = sub( mant, 8 );
Direct computation of xMc[0..12] using table 5.5.
temp1= sub( 6, exp ); /normalization by the exponent/
temp2 = NRFAC[mant]; /see table 5.5 (inverse mantissa)/
|== FOR i = 0 to 12:
| temp = xM[i] << temp1;
| temp = mult( temp , temp2 );
| xMc[i] = add( ( temp >> 12 ), 4 ); /See note below/
|== NEXT I:
NOTE: This equation is used to make all the xMc[i] positive.
Keep in memory exp and mant for the following inverse APCM quantizer.
5.2.16 APCM inverse quantization
This part is for decoding the RPE sequence of coded xMc[0..12] samples to obtain the xMp[0..12] array. Table 5.6 is used to get the mantissa of xmaxc (FAC[0..7]).
temp1 = FAC[mant]; see 5.2.15 for mant
temp2= sub( 6, exp ); see 5.2.15 for exp
temp3= 1 << sub( temp2, 1 );
|== FOR i =0 to 12:
| temp = sub( ( xMc[i] << 1 ), 7 ); /See note below/
| temp = temp << 12;
| temp = mult_r( temp1, temp );
| temp = add( temp, temp3 );
| xMp[i] = temp >> temp2;
|== NEXT i;
NOTE: This subtraction is used to restore the sign of xMc[i].
5.2.17 RPE grid positioning
This procedure computes the reconstructed long term residual signal ep[0..39] for the LTP analysis filter. The inputs are the Mc which is the grid position selection and the xMp[0..12] decoded RPE samples which are upsampled by a factor of 3 by inserting zero values.
|== FOR k = 0 to 39:
| ep[k] = 0;
|== NEXT k:
|== FOR i = 0 to 12:
| ep[Mc +(3*i)] = xMp[i];
|== NEXT i:
5.2.18 Update of the reconstructed short term residual signal dp[‑120..‑1]
This procedure adds the reconstructed long term residual signal ep[0..39] to the estimated signal dpp[0..39] from the long term analysis filter to compute the reconstructed short term residual signal dp[‑40..‑1]; also the reconstructed short term residual array dp[‑120..‑41] is updated.
|== FOR k = 0 to 79:
| dp[‑120+k] = dp[‑80+k];
|== NEXT k:
|== FOR k = 0 to 39:
| dp[‑40+k] = add( ep[k], dpp[k] );
|== NEXT k:
Keep the array dp[‑120..‑1] in memory for the next sub‑segment.
Initial value: dp[‑120..‑1]=0;
5.3 Fixed point implementation of the RPE‑LTP decoder
Only the synthesis filter and the de‑emphasis procedure are different from the procedures found in the RPE‑LTP coder. Procedures 5.3.1 and 5.3.2 are executed for each sub‑segment (four times per frame). Procedures 5.3.3, 5.3.4 and 5.3.5 are executed once per frame.
5.3.1 RPE decoding clause
Procedures 5.2.15 (only the part to get mant and exp of xmaxc), 5.2.16 and 5.2.17 are used to obtain the reconstructed long term residual signal erp[0..39] signal from the received parameters for each sub‑segment (i.e. Mcr, xmaxcr, xmcr[0..12]).
5.3.2 Long term synthesis filtering
This procedure uses the bcr and Ncr parameter to realize the long term synthesis filtering. The decoding of bcr needs the use of table 5.3b.
‑ Nr is the received and decoded LTP lag.
‑ An array drp[‑120..39] is used in this procedure.
The elements for ‑120 to ‑1 of the array drp are kept in memory for the long term synthesis filter. For each sub‑segment (40 samples), this procedure computes the drp[0..39] to be fed to the synthesis filter.
Check the limits of Nr.
Nr = Ncr;
IF ( Ncr < 40 ) THEN Nr = nrp;
IF ( Ncr > 120 ) THEN Nr = nrp;
nrp= Nr;
Keep the nrp value for the next sub‑segment.
Initial value: nrp=40;
Decoding of the LTP gain bcr.
brp = QLB[bcr]
Computation of the reconstructed short term residual signal drp[0..39].
|== FOR k = 0 to 39:
| drpp = mult_r( brp, drp[k-Nr] );
| drp[k] = add( erp[k], drpp );
|== NEXT k:
Update of the reconstructed short term residual signal drp[‑1..‑120].
|== FOR k = 0 to 119:
| drp[‑120+k] = drp[‑80+k];
|== NEXT k:
Keep the array drp[‑120..‑1] for the next sub‑segment.
Initial value: drp[‑120..‑1]=0;
5.3.3 Computation of the decoded reflection coefficients
This procedure (which is executed once per frame) is the same as the one described in the CODER part. For decoding of the received LARcr[1..8], see procedure 5.2.8. For the interpolation of the decoded Log.‑Area Ratios, see procedure 5.2.9.1 and for the computation of the reflection coefficients rrp[1..8], see procedure 5.2.9.2.
5.3.4 Short term synthesis filtering clause
This procedure uses the drp[0..39] signal and produces the sr[0..159] signal which is the output of the short term synthesis filter. For ease of explanation, a temporary array wt[0..159] is used.
Initialization of the array wt[0..159].
For the first sub‑segment in a frame:
|== FOR k = 0 to 39:
| wt[k] = drp[k];
|== NEXT k:
For the second sub‑segment in a frame:
|== FOR k = 0 to 39:
| wt[40+k] = drp[k];
|== NEXT k:
For the third sub‑segment in a frame:
|== FOR k = 0 to 39:
| wt[80+k] = drp[k];
|== NEXT k:
For the fourth sub‑segment in a frame:
|== FOR k = 0 to 39:
| wt[120+k] = drp[k];
|== NEXT k:
As the call of the short term synthesis filter procedure can be done in many ways (see the interpolation of the LAR coefficient), it is assumed that the computation begins with index k_start (for arrays wt[..] and sr[..]) and stops with index k_end (k_start and k_end are defined in 5.2.9.1). The procedure also needs to keep the array v[0..8] in memory between calls.
|== FOR k = k_start to k_end:
| sri = wt[k];
|==== FOR i = 1 to 8:
| sri = sub( sri, mult_r( rrp[9-i], v[8-i] ) );
| v[9-i] = add( v[8-i], mult_r( rrp[9-i], sri ) );
|==== NEXT i:
| sr[k] = sri;
| v[0] = sri;
|== NEXT k:
Keep the array v[0..8] in memory for the next call.
Initial value: v[0..8]=0;
Post‑processing
5.3.5 De‑emphasis filtering
|== FOR k = 0 to 159:
| temp = add( sr[k], mult_r( msr, 28180 ) );
| msr = temp;
| sro[k] = msr;
|== NEXT k:
Keep msr in memory for the next frame.
Initial value: msr=0;
5.3.6 Upscaling of the output signal
|== FOR k = 0 to 159:
| srop[k] = add( sro[k], sro[k] );
|== NEXT k:
5.3.7 Truncation of the output variable
|== FOR k = 0 to 159:
| srop[k] = srop[k] >> 3;
| srop[k] = srop[k] << 3;
|== NEXT k:
The output format is the following:
S.v.v.v.v.v.v.v.v.v.v.v.v.0.0.0 (2’s complement).
Where S is the sign bit, v a valid bit.
NOTE: When a linear to A‑law compression is needed, then the sub‑block COMPRESS of CCITT G721 recommendation shall be used with inputs:
SR = srop[k] >> 3;
LAW = 1;
When a linear to ‑law compression is needed, then the sub‑block COMPRESS of CCITT G721 recommendation shall be used with inputs:
SR = srop[k] >> 3;
LAW = 0;
5.4 Tables used in the fixed point implementation of the RPE‑LTP coder and decoder
Table 5.1: Quantization of the Log.‑Area Ratios
i |
A[i] |
B[i] |
MIC[i] |
MAC[i] |
1 |
20480 |
0 |
‑32 |
31 |
2 |
20480 |
0 |
‑32 |
31 |
3 |
20480 |
2048 |
‑16 |
15 |
4 |
20480 |
‑2560 |
‑16 |
15 |
5 |
13964 |
94 |
‑8 |
7 |
6 |
15360 |
‑1792 |
‑8 |
7 |
7 |
8534 |
‑341 |
‑4 |
3 |
8 |
9036 |
‑1144 |
‑4 |
3 |
Table 5.2: Tabulation of 1/A[1..8]
i |
INVA[i] |
1 |
13107 |
2 |
13107 |
3 |
13107 |
4 |
13107 |
5 |
19223 |
6 |
17476 |
7 |
31454 |
8 |
29708 |
Table 5.3a: Decision level of the LTP gain quantizer
bc |
DLB[bc] |
0 |
6554 |
1 |
16384 |
2 |
26214 |
3 |
32767 |
Table 5.3b: Quantization levels of the LTP gain quantizer
bc |
QLB[bc] |
0 |
3277 |
1 |
11469 |
2 |
21299 |
3 |
32767 |
Table 5.4: Coefficients of the weighting filter
i |
H[i] |
0 |
‑134 |
1 |
‑374 |
2 |
0 |
3 |
2054 |
4 |
5741 |
5 |
8192 |
6 |
5741 |
7 |
2054 |
8 |
0 |
9 |
‑374 |
10 |
‑134 |
Table 5.5: Normalized inverse mantissa used to compute xM/xmax
i |
NRFAC[i] |
0 |
29128 |
1 |
26215 |
2 |
23832 |
3 |
21846 |
4 |
20165 |
5 |
18725 |
6 |
17476 |
7 |
16384 |
Table 5.6: Normalized direct mantissa used to compute xM/xmax
i |
FAC[i] |
0 |
18431 |
1 |
20479 |
2 |
22527 |
3 |
24575 |
4 |
26623 |
5 |
28671 |
6 |
30719 |
7 |
32767 |