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; 
	} 
}