www.pudn.com > speakFreely-code.zip > acelp_pf.c
/*======================================================================*/
/* Enhanced Variable Rate Codec - Bit-Exact C Specification */
/* Copyright (C) 1997-1998 Telecommunications Industry Association. */
/* All rights reserved. */
/*----------------------------------------------------------------------*/
/* Note: Reproduction and use of this software for the design and */
/* development of North American Wideband CDMA Digital */
/* Cellular Telephony Standards is authorized by the TIA. */
/* The TIA does not authorize the use of this software for any */
/* other purpose. */
/* */
/* The availability of this software does not provide any license */
/* by implication, estoppel, or otherwise under any patent rights */
/* of TIA member companies or others covering any use of the */
/* contents herein. */
/* */
/* Any copies of this software or derivative works must include */
/* this and all other proprietary notices. */
/*======================================================================*/
#include "acelp_pf.h"
#include "mathevrc.h"
#define NB_TRACK 5
#define STEP 5
#define L_SUBFR 55
#define L_SUBFR2 55
/*Note: Vector xn[], res2[], code[], y2[] and h1[] should be of lenght 55 !!! */
/*---------------------------------------------------------------------------*
* Function ACELP_code() *
* ~~~~~~~~~~~~~~~~~~~~~~ *
* Find Algebraic codebook. *
*--------------------------------------------------------------------------*/
void ACELP_Code(
Shortword xn[], /* (i) :Target signal for codebook. */
Shortword res2[], /* (i) :Residual after pitch contribution */
Shortword h1[], /* (i) :Impulse response of filters. */
Shortword T0, /* (i) :Pitch lag. */
Shortword pitch_gain, /* (i) :Pitch gain. */
Shortword l_subfr, /* (i) :Subframe lenght. */
Shortword code[], /* (o) :Innovative vector. */
Shortword * gain_code, /* (o) :Innovative vector gain. */
Shortword y2[], /* (o) :Filtered innovative vector. */
Shortword * index, /* (o) :Index of codebook + signs */
Shortword choice /* (i) :Choice of innovative codebook */
/* 0 -> 10 bits */
/* 1 -> 35 bits */
)
{
Shortword i, pit_sharp;
Shortword dn[L_SUBFR2];
/*-----------------------------------------------------------------*
* - Find pitch sharpening. *
*-----------------------------------------------------------------*/
/**===========================================================\
Since the pitch gain is scaled by 1/2, therefore, the pitch_gain
should enlarge 2 to compensate the scale factor
==============================================================*/
pit_sharp = pitch_gain;
/* if(pit_sharp > 0.9) pit_sharp = 0.9; */
if (pit_sharp > 14746)
pit_sharp = 14746;
/* if(pit_sharp < 0.2) pit_sharp = 0.2; */
if (pit_sharp < 3277)
pit_sharp = 3277;
pit_sharp = shl(pit_sharp,1);
/*-----------------------------------------------------------------*
* - Include fixed-gain pitch contribution into impulse resp. h1[] *
*-----------------------------------------------------------------*/
for (i = T0; i < l_subfr; i++)
{ /* h[i] += pitch_sharp*h[i-T0] */
h1[i] = add(h1[i], mult(h1[i - T0], pit_sharp));
}
/*-----------------------------------------------------------------*
* Compute correlation between target "xn[]" and "h1[]". *
*-----------------------------------------------------------------*/
/* Put xn[i] = res2[i] = 0; for i>l_subfr */
for (i = l_subfr; i < L_SUBFR; i++)
xn[i] = res2[i] = 0;
/* Compute correlation between target x[] and H[] */
cor_h_x(h1, xn, dn);
/*-----------------------------------------------------------------*
* - Innovative codebook search *
*-----------------------------------------------------------------*/
if (choice == 0)
{
code_3i54_10bits(dn, l_subfr, h1, code, y2, index);
}
else
{
code_8i55_35bits(dn, res2, l_subfr, h1, code, y2, index);
}
/*-----------------------------------------------------------------*
* Include fixed-gain pitch contribution into code[]. *
*-----------------------------------------------------------------*/
for (i = T0; i < l_subfr; i++)
{ /* code[i] += pitch_sharp*code[i-T0] */
code[i] = add(code[i], mult(code[i - T0], pit_sharp));
}
/*-----------------------------------------------------------------*
* find gain of code. *
*-----------------------------------------------------------------*/
*gain_code = G_code(xn, y2, l_subfr);
return;
}
/*-------------------------------------------------------------------*
* Function cor_h_x() *
* ~~~~~~~~~~~~~~~~~~~ *
* Compute correlation between target "x[]" and "h[]". *
*-------------------------------------------------------------------*
*-------------------------------------------------------------------*/
void cor_h_x(
Shortword h[], /* (i) Q12 : impulse response of weighted synthesis filter */
Shortword x[], /* (i) Q0 : correlation between target and h[] */
Shortword dn[] /* (o) Q0 : correlation between target and h[] */
)
{
Shortword i, j, k;
Longword s, y32[L_SUBFR], max, tot;
/* first keep the result on 32 bits and find absolute maximum */
tot = 5;
for (k = 0; k < NB_TRACK; k++)
{
max = 0;
for (i = k; i < L_SUBFR; i += STEP)
{
s = 0;
for (j = i; j < L_SUBFR; j++)
s = L_mac(s, x[j], h[j - i]);
y32[i] = s;
s = L_abs(s);
if (L_sub(s, max) > (Longword) 0)
max = s;
}
tot = L_add(tot, L_shr(max, 1)); /* tot += (2.0 x max) / 4.0 */
}
/* Find the number of right shifts to do on y32[] so that */
/* 2.0 x sumation of all max of dn[] in each track not saturate. */
j = sub(norm_l(tot), 2); /* multiply tot by 4 */
for (i = 0; i < L_SUBFR; i++)
{
dn[i] = round(L_shl(y32[i], j));
}
}
/*-------------------------------------------------------------------*
* Function G_code() *
* ~~~~~~~~~~~~~~~~~~ *
* Compute gain of code. *
*-------------------------------------------------------------------*/
Shortword G_code(
Shortword xn2[], /* out: Q0 Gain of innovation code. */
Shortword y2[], /* in: Q10 Filtered inovation vector */
Shortword l_subfr)
{
Shortword i;
Shortword xy, yy, exp_xy, exp_yy, gain;
Shortword scal_y2[L_SUBFR];
Longword s;
/* Scale down Y[] by 2 to avoid overflow */
for (i = 0; i < l_subfr; i++)
{
scal_y2[i] = shr(y2[i], 1); /* Q10 --> Q9 */
}
/* Compute scalar product */
s = 1; /* Avoid case of all zeros */
for (i = 0; i < l_subfr; i++)
s = L_mac(s, xn2[i], scal_y2[i]);
exp_xy = norm_l(s);
xy = extract_h(L_shl(s, exp_xy));
/* If (xy < 0) gain = 0 */
if (xy <= 0)
return ((Shortword) 0);
/* Compute scalar product */
s = 0;
for (i = 0; i < l_subfr; i++)
s = L_mac(s, scal_y2[i], scal_y2[i]);
exp_yy = norm_l(s);
yy = extract_h(L_shl(s, exp_yy));
/* compute gain = xy/yy */
xy = shr(xy, 1); /* Be sure xy < yy */
gain = divide_s(xy, yy);
/* Denormalization of division */
i = add(exp_xy, 5);
i = sub(i, exp_yy);
i=add(i,1);
gain = shr(gain, i);
return (gain);
}