www.pudn.com > speakFreely-code.zip > a2lsp.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. */
/*======================================================================*/
/* Memory Usage: */
/* ROM: 4 */
/* Static/Global RAM: 0 */
/* Stack/Local RAM: 21 */
/*----------------------------------------------------------------------*/
/*
* pctolsp - convert pc to lsp
*
* NOTES: 1. This routine is hardwired for 10th order
* 2. The routine uses 3 stage uniform grid quantization of lsp.
*/
#include "macro.h"
#include "mathevrc.h"
#include "mathdp31.h"
#include "mathadv.h"
#define STEPSNUM 4
long interpolation_cos129(short);
void a2lsp(short *freq, short *a)
{
static long LSTEPS[4] =
{13636520, 6818260, 3409130, 1704565};
int lspnumber;
int root, notlast;
long Ltemp;
long Lq[11], t[7], s[6];
long Lprev[2];
int offset;
int iswitch;
long Lfrequency, LastFreq;
long LSTEP;
int STEPindex;
short num;
short j;
short scale;
scale = 5;
LastFreq = 0;
t[0] = 0;
t[1] = L_shr(L_deposit_h(0x1000), scale);
Lq[0] = t[1];
/* calculate q[z] and p[z] , they are all stored in q */
for (j = 1; j < 6; j++)
{
Lq[j] = L_add(L_shr(L_deposit_h(a[j - 1]), scale),
L_shr(L_deposit_h(a[10 - j]), scale));
Lq[j] = L_sub(Lq[j], Lq[j - 1]);
}
Lq[5] = L_shr(Lq[5], 1);
offset = 5;
Lq[1 + offset] = L_add(L_shr(L_deposit_h(sub(a[0], a[9])), scale), Lq[0]);
for (j = 2; j < 6; j++)
{
Lq[j + offset] = L_sub(L_shr(L_deposit_h(a[j - 1]), scale),
L_shr(L_deposit_h(a[10 - j]), scale));
Lq[j + offset] = L_add(Lq[j + offset], Lq[j - 1 + offset]);
}
Lq[5 + offset] = L_shr(Lq[5 + offset], 1);
Lprev[0] = LW_MAX;
Lprev[1] = LW_MAX;
lspnumber = 0;
notlast = TRUE;
iswitch = 0;
Lfrequency = 0x00000000L;
while (notlast)
{
root = TRUE;
if (iswitch)
offset = 5;
else
offset = 0;
STEPindex = 0; /* Start with low resolution grid */
LSTEP = LSTEPS[STEPindex];
while (root)
{
Ltemp = L_shr(interpolation_cos129(round(Lfrequency)), 1);
for (j = 1; j < 5; j++)
s[j] = Ltemp;
s[5] = L_shr(Ltemp, 1);
for (j = 2; j < 7; j++)
{
t[j] = L_mpy_ll(s[j - 1], t[j - 1]);
t[j] = L_shl(t[j], 2);
t[j] = L_sub(t[j], t[j - 2]);
t[j] = L_add(t[j], Lq[j - 1 + offset]);
}
num = (((t[6] > 0) && (Lprev[iswitch] < 0)) ||
((t[6] < 0) && (Lprev[iswitch] > 0)) || (t[6] == 0));
if ((num == 1) || (Lfrequency >= 0x40000000L))
{
if (STEPindex == STEPSNUM - 1)
{
if (L_abs(t[6]) < L_abs(Lprev[iswitch]))
freq[lspnumber] = round(Lfrequency);
else
freq[lspnumber] = round(L_sub(Lfrequency, LSTEP));
if ((Lprev[iswitch]) < 0)
Lprev[iswitch] = LW_MAX; /*was 9e9 */
else
Lprev[iswitch] = LW_MIN; /*was 9e9 */
root = FALSE;
Lfrequency = LastFreq;
STEPindex = 0;
}
else
{
if (STEPindex == 0)
LastFreq = Lfrequency;
Lfrequency =
L_sub(Lfrequency, LSTEPS[++STEPindex]);
/* Go back one grid step */
LSTEP = (LSTEPS[STEPindex]);
}
}
else
{
Lprev[iswitch] = t[6];
Lfrequency = L_add(Lfrequency, LSTEP);
}
}
lspnumber++;
if (lspnumber > ORDER - 1)
notlast = FALSE;
iswitch = 1 - iswitch;
}
}