⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lpc_lib.c

📁 MELPe 1200 bps, fixed point
💻 C
📖 第 1 页 / 共 3 页
字号:
/* ================================================================== */
/*                                                                    */ 
/*    Microsoft Speech coder     ANSI-C Source Code                   */
/*    SC1200 1200 bps speech coder                                    */
/*    Fixed Point Implementation      Version 7.0                     */
/*    Copyright (C) 2000, Microsoft Corp.                             */
/*    All rights reserved.                                            */
/*                                                                    */ 
/* ================================================================== */

/*

2.4 kbps MELP Proposed Federal Standard speech coder

Fixed-point C code, version 1.0

Copyright (c) 1998, Texas Instruments, Inc.

Texas Instruments has intellectual property rights on the MELP
algorithm.	The Texas Instruments contact for licensing issues for
commercial and non-government use is William Gordon, Director,
Government Contracts, Texas Instruments Incorporated, Semiconductor
Group (phone 972 480 7442).

The fixed-point version of the voice codec Mixed Excitation Linear
Prediction (MELP) is based on specifications on the C-language software
simulation contained in GSM 06.06 which is protected by copyright and
is the property of the European Telecommunications Standards Institute
(ETSI). This standard is available from the ETSI publication office
tel. +33 (0)4 92 94 42 58. ETSI has granted a license to United States
Department of Defense to use the C-language software simulation contained
in GSM 06.06 for the purposes of the development of a fixed-point
version of the voice codec Mixed Excitation Linear Prediction (MELP).
Requests for authorization to make other use of the GSM 06.06 or
otherwise distribute or modify them need to be addressed to the ETSI
Secretariat fax: +33 493 65 47 16.

*/

/* =========================== */
/* lpc_lib.c: LPC subroutines. */
/* =========================== */

/*	compiler include files	*/

#include <stdio.h>

#include "sc1200.h"
#include "macro.h"
#include "mathhalf.h"
#include "mathdp31.h"
#include "math_lib.h"
#include "mat_lib.h"
#include "lpc_lib.h"
#include "constant.h"
#include "global.h"
#include "dsp_sub.h"


#define ALMOST_ONE_Q14		16382                            /* ((1 << 14)-2) */
#define ONE_Q25				33554431L                            /* (1 << 25) */
#define ONE_Q26				67108864L                            /* (1 << 26) */
#define LOW_LIMIT			54  /* lower limit of return value for lpc_aejw() */
                                 /* to prevent overflow of weighting function */
#define MAX_LOOPS			10
#define DFTLENGTH			512
#define DFTLENGTH_D2		(DFTLENGTH/2)
#define DFTLENGTH_D4		(DFTLENGTH/4)

/* Prototype */

static void		lsp_to_freq(Shortword lsp[], Shortword freq[], Shortword order);
static Shortword	lpc_refl2pred(Shortword refc[], Shortword lpc[],
								  Shortword order);


/* LPC_ACOR                                                                   */
/*		Compute autocorrelations based on windowed speech frame               */
/*                                                                            */
/*	Synopsis: lpc_acor(input, window, r, hf_correction, order, npts)          */
/*		Input:                                                                */
/*			input- input vector (npts samples, s[0..npts-1])                  */
/*			win_cof- window vector (npts samples, s[0..npts-1])               */
/*			hf_correction- high frequency correction value                    */
/*			order- order of lpc filter                                        */
/*			npts- number of elements in window                                */
/*		Output:                                                               */
/*			autocorr- output autocorrelation vector (order + 1 samples,       */
/*                    autocorr[0..order])                                     */
/*                                                                            */
/*	Q values: input - Q0, win_cof - Q15, hf_correction - Q15                  */

void lpc_acor(Shortword input[], const Shortword win_cof[],
			  Shortword autocorr[], Shortword hf_correction, Shortword order,
			  Shortword npts)
{
	/* Lag window coefficients */
	static const Shortword		lagw_cof[EN_FILTER_ORDER - 1] = {
		32756, 32721, 32663, 32582, 32478, 32351, 32201, 32030, 31837, 31622,
		31387, 31131, 30855, 30560, 30246, 29914
	};
	register Shortword	i, j;
	Longword	L_temp;
	Shortword	*inputw;
	Shortword	norm_var, scale_fact, temp;


	/* window optimized for speed and readability.  does windowing and        */
	/* autocorrelation sequentially and in the usual manner                   */

	inputw = v_get(npts);
	for (i = 0; i < npts; i++){
		inputw[i] = mult(win_cof[i], shr(input[i], 4));
	}

	/* Find scaling factor */
	L_temp = L_v_magsq(inputw, npts, 0, 1);
	if (L_temp){
		norm_var = norm_l(L_temp);
		norm_var = sub(4, shr(norm_var, 1));
		if (norm_var < 0)
			norm_var = 0;
	} else
		norm_var = 0;

	for (i = 0; i < npts; i++){
		inputw[i] = shr(mult(win_cof[i], input[i]), norm_var);
	}

	/* Compute r[0] */
	L_temp = L_v_magsq(inputw, npts, 0, 1);
	if (L_temp > 0){
		/* normalize with 1 bit of headroom */
		norm_var = norm_l(L_temp);
		norm_var = sub(norm_var, 1);
		L_temp = L_shl(L_temp, norm_var);

		/* High frequency correction */
		L_temp = L_add(L_temp, L_mpy_ls(L_temp, hf_correction));

		/* normalize result */
		temp = norm_s(extract_h(L_temp));
		L_temp = L_shl(L_temp, temp);
		norm_var = add(norm_var, temp);
		autocorr[0] = round(L_temp);

		/* Multiply by 1/autocorr[0] for full normalization */
		scale_fact = divide_s(ALMOST_ONE_Q14, autocorr[0]);
		L_temp = L_shl(L_mpy_ls(L_temp, scale_fact), 1);
		autocorr[0] = round(L_temp);

	} else {
		norm_var = 0;
		autocorr[0] = ONE_Q15;                                    /* 1 in Q15 */
		scale_fact = 0;
	}

	/* Compute remaining autocorrelation terms */
	for (j = 1; j <= order; j++){
		L_temp = 0;
		for (i = j; i < npts; i++)
			L_temp = L_mac(L_temp, inputw[i], inputw[i - j]);
		L_temp = L_shl(L_temp, norm_var);

		/* Scaling */
		L_temp = L_shl(L_mpy_ls(L_temp, scale_fact), 1);

		/* Lag windowing */
		L_temp = L_mpy_ls(L_temp, lagw_cof[j - 1]);

		autocorr[j] = round(L_temp);
	}
	v_free(inputw);
}


/* Name: lpc_aejw- Compute square of A(z) evaluated at exp(jw)                */
/* Description:                                                               */
/*		Compute the magnitude squared of the z-transform of                   */
/*                                                                            */
/*		A(z) = 1 + a(1)z^-1 + ... + a(p)z^-p                                  */
/*                                                                            */
/*		evaluated at z = exp(jw)                                              */
/*	 Inputs:                                                                  */
/*		lpc (a)- LPC filter (a[0] is undefined, a[1..p])                      */
/*		omega (w)- radian frequency                                           */
/*		order (p)- predictor order                                            */
/*	 Returns:                                                                 */
/* 		|A(exp(jw))|^2                                                        */
/*	 See_Also: cos(3), sin(3)                                                 */
/*	 Includes:                                                                */
/*		lpc.h                                                                 */
/*	 Systems and Info. Science Lab                                            */
/*	 Copyright (c) 1995 by Texas Instruments, Inc.	All rights reserved.      */
/*                                                                            */
/* Q values:                                                                  */
/*      lpc - Q12, omega - Q15, return - Q19                                  */

Longword lpc_aejw(Shortword lpc[], Shortword omega, Shortword order)
{
	register Shortword	i;
	Shortword	c_re, c_im;
	Shortword	cs, sn, temp;
	Shortword	temp1, temp2;
	Longword	L_temp;


	if (order == 0)
		return((Longword) ONE_Q19);

	/* use horners method                                                     */
	/* A(exp(jw)) = 1+ e(-jw)[a(1) + e(-jw)[a(2) + e(-jw)[a(3) +..            */
	/*				...[a(p-1) + e(-jw)a(p)]]]]                               */

	cs = cos_fxp(omega);                                          /* Q15 */
	sn = negate(sin_fxp(omega));                               /* Q15 */

	temp1 = lpc[order - 1];
	c_re = shr(mult(cs, temp1), 3);                            /* -> Q9 */
	c_im = shr(mult(sn, temp1), 3);                            /* -> Q9 */

	for (i = sub(order, 2); i >= 0; i--){
		/* add a[i] */
		temp = shr(lpc[i], 3);
		c_re = add(c_re, temp);

		/* multiply by exp(-jw) */
		temp = c_im;
		temp1 = mult(cs, temp);                                /* temp1 in Q9 */
		temp2 = mult(sn, c_re);                               /* temp2 in Q9 */
		c_im = add(temp1, temp2);
		temp1 = mult(cs, c_re);                            /* temp1 in Q9 */
		temp2 = mult(sn, temp);                           /* temp2 in Q9 */
		c_re = sub(temp1, temp2);
	}

	/* add one */
	c_re = add(c_re, ONE_Q9);

	/* L_temp in Q19 */
	L_temp = L_add(L_mult(c_re, c_re), L_mult(c_im, c_im));
	if (L_temp < LOW_LIMIT)
		L_temp = (Longword) LOW_LIMIT;

	return(L_temp);
}


/* Name: lpc_bwex- Move the zeros of A(z) toward the origin.                  */
/*	Aliases: lpc_bw_expand                                                    */
/*	Description:                                                              */
/*		Expand the zeros of the LPC filter by gamma, which                    */
/*		moves each zero radially into the origin.                             */
/*                                                                            */
/*		for j = 1 to p                                                        */
/*			aw[j] = a[j]*gamma^j                                              */
/*		(Can also be used to perform an exponential windowing procedure).     */
/*	Inputs:                                                                   */
/*		lpc (a)- lpc vector (order p, a[1..p])                                */
/*		gamma- the bandwidth expansion factor                                 */
/*		order (p)- order of lpc filter                                        */
/*	Outputs:                                                                  */
/*		aw- the bandwidth expanded LPC filter                                 */
/*	Returns: NULL                                                             */
/*	See_Also: lpc_lagw(3l)                                                    */
/*	Includes:                                                                 */
/*		lpc.h                                                                 */
/*                                                                            */
/*	Systems and Info. Science Lab                                             */
/*	Copyright (c) 1995 by Texas Instruments, Inc.  All rights reserved.       */
/*                                                                            */
/*	Q values: lpc[], aw[] - Q12, gamma - Q15, gk - Q15                        */

Shortword lpc_bwex(Shortword lpc[], Shortword aw[], Shortword gamma,
				   Shortword order)
{
	register Shortword	i;
	Shortword	gk;                                              /* gk is Q15 */

	gk = gamma;

	for (i = 0; i < order; i++){
		aw[i] = mult(lpc[i], gk);
		gk = mult(gk, gamma);
	}
	return(0);
}


/* Name: lpc_clmp- Sort and ensure minimum separation in LSPs.                */
/*	Aliases: lpc_clamp                                                        */
/*	Description:                                                              */
/*		Ensure that all LSPs are ordered and separated                        */
/*		by at least delta.	The algorithm isn't guarenteed                    */
/*		to work, so it prints an error message when it fails                  */
/*		to sort the LSPs properly.                                            */
/*	Inputs:                                                                   */
/*		lsp (w)- lsp vector (order p, w[1..p])                                */
/*		delta- the clamping factor                                            */
/*		order (p)- order of lpc filter                                        */
/*	Outputs:                                                                  */
/*		lsp (w)- the sorted and clamped lsps                                  */
/*	Returns: NULL                                                             */
/*	See_Also:                                                                 */
/*	Includes:                                                                 */
/*		lpc.h                                                                 */
/*	Bugs:                                                                     */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -