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

📄 melp_sub.c

📁 MELPe 1200 bps, fixed point
💻 C
📖 第 1 页 / 共 3 页
字号:
/*

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.

*/

/* ===================================== */
/* melp_sub.c: MELP-specific subroutines */
/* ===================================== */

#include "sc1200.h"
#include "mathhalf.h"
#include "math_lib.h"
#include "mat_lib.h"
#include "dsp_sub.h"
#include "melp_sub.h"
#include "pit_lib.h"
#include "constant.h"
#include "coeff.h"
#include "global.h"

/* Filter orders */

#define CONSTANT_SCALE		FALSE
#define MINGAIN				0
#define LOG10OF2X2			1233                         /* 2*log10(2) in Q11 */
#define GAIN_INT_DB_Q8		1280                              /* 5 * (1 << 8) */
#define ONE_Q8				256                                   /* (1 << 8) */
#define THREE_Q8			768                               /* 3 * (1 << 8) */
#define SIX_Q12				24576                            /* 6 * (1 << 12) */
#define TEN_Q11				20480                           /* 10 * (1 << 11) */
#define X0001_Q8			0                             /* 0.001 * (1 << 8) */
#define X01_Q14				1638                           /* 0.1 * (1 << 14) */
#define N2_Q11				-4096                           /* -2 * (1 << 11) */
#define M01_Q15				-3276                         /* -0.1 * (1 << 15) */
#define M10_Q11				-20480                         /* -10 * (1 << 11) */


/* Name: bpvc_ana.c                                                           */
/*  Description: Bandpass voicing analysis                                    */
/*  Inputs:                                                                   */
/*    speech[] - input speech signal                                          */
/*    fpitch[] - initial (floating point) pitch estimates                     */
/*  Outputs:                                                                  */
/*    bpvc[] - bandpass voicing decisions                                     */
/*    pitch[] - frame pitch estimates                                         */
/*  Returns: void                                                             */
/*                                                                            */
/*  Copyright (c) 1995,1997 by Texas Instruments, Inc.  All rights reserved.  */
/*                                                                            */
/* Q values: speech - Q0, fpitch - Q7, bpvc - Q14, pitch - Q7                 */

void bpvc_ana(Shortword speech[], Shortword fpitch[], Shortword bpvc[],
			  Shortword *pitch)
{
	register Shortword	i, section;
	static Shortword	bpfsp[NUM_BANDS][PITCH_FR - FRAME];
	static Shortword	bpfdelin[NUM_BANDS][BPF_ORD];
	static Shortword	bpfdelout[NUM_BANDS][BPF_ORD];
	static Shortword	envdel[NUM_BANDS][ENV_ORD];
	static Shortword	envdel2[NUM_BANDS];
	static BOOLEAN	firstTime = TRUE;
	Shortword	sigbuf[BPF_ORD + PITCH_FR];
	Shortword	pcorr, temp, scale;
	Shortword	filt_index;



	if (firstTime){
		for (i = 0; i < NUM_BANDS; i++){
			v_zap(bpfsp[i], PITCH_FR - FRAME);
			v_zap(bpfdelin[i], BPF_ORD);
			v_zap(bpfdelout[i], BPF_ORD);
		}
		for (i = 0; i < NUM_BANDS; i++)
			v_zap(envdel[i], ENV_ORD);
		v_zap(envdel2, NUM_BANDS);
		firstTime = FALSE;
	}

	/* Filter lowest band and estimate pitch */
	v_equ(&sigbuf[BPF_ORD], bpfsp[0], PITCH_FR - FRAME);
	v_equ(&sigbuf[BPF_ORD + PITCH_FR - FRAME],
		  &speech[PITCH_FR - FRAME - PITCHMAX], FRAME);

	for (section = 0; section < BPF_ORD/2; section ++){
		iir_2nd_s(&sigbuf[BPF_ORD + PITCH_FR - FRAME],
				  &bpf_den[section*3], &bpf_num[section*3],
				  &sigbuf[BPF_ORD + PITCH_FR - FRAME], &bpfdelin[0][section*2],
				  &bpfdelout[0][section*2], FRAME);
	}
	v_equ(bpfsp[0], &sigbuf[BPF_ORD + FRAME], PITCH_FR - FRAME);

	/* Scale signal for pitch correlations */
	f_pitch_scale(&sigbuf[BPF_ORD], &sigbuf[BPF_ORD], PITCH_FR);

	*pitch = frac_pch(&sigbuf[BPF_ORD + PITCHMAX], bpvc, fpitch[0], 5,
					  PITCHMIN, PITCHMAX, PITCHMIN_Q7, PITCHMAX_Q7,
					  MINLENGTH);

	for (i = 1; i < NUM_PITCHES; i++){
		temp = frac_pch(&sigbuf[BPF_ORD + PITCHMAX], &pcorr, fpitch[i], 5,
						PITCHMIN, PITCHMAX, PITCHMIN_Q7, PITCHMAX_Q7,
						MINLENGTH);

		/* choose largest correlation value */
		if (pcorr > bpvc[0]){
			*pitch = temp;
			bpvc[0] = pcorr;
		}
	}

	/* Calculate bandpass voicing for frames */
	for (i = 1; i < NUM_BANDS; i++){
		/* Bandpass filter input speech */
		v_equ(&sigbuf[BPF_ORD], bpfsp[i], PITCH_FR - FRAME);
		v_equ(&sigbuf[BPF_ORD + PITCH_FR - FRAME],
			  &speech[PITCH_FR - FRAME - PITCHMAX], FRAME);

		for (section = 0; section < BPF_ORD/2; section++){
			filt_index = (Shortword) (i*(BPF_ORD/2)*3 + section*3);
			iir_2nd_s(&sigbuf[BPF_ORD + PITCH_FR - FRAME],
					  &bpf_den[filt_index], &bpf_num[filt_index],
					  &sigbuf[BPF_ORD + PITCH_FR - FRAME],
					  &bpfdelin[i][section*2], &bpfdelout[i][section*2],
					  FRAME);
		}
		v_equ(bpfsp[i], &sigbuf[BPF_ORD + FRAME], PITCH_FR - FRAME);

		/* Scale signal for pitch correlations */
		scale = f_pitch_scale(&sigbuf[BPF_ORD], &sigbuf[BPF_ORD], PITCH_FR);

		/* Check correlations for each frame */
		temp = frac_pch(&sigbuf[BPF_ORD + PITCHMAX], &bpvc[i], *pitch, 0,
						PITCHMIN, PITCHMAX, PITCHMIN_Q7, PITCHMAX_Q7,
						MINLENGTH);

		/* Calculate envelope of bandpass filtered input speech */
		/* update delay buffers without scaling */
		temp = shr(envdel2[i], scale);
		envdel2[i] = shr(sigbuf[BPF_ORD + FRAME - 1], (Shortword) (-scale));
		v_equ_shr(&sigbuf[BPF_ORD - ENV_ORD], envdel[i], scale, ENV_ORD);
		envelope(&sigbuf[BPF_ORD], temp, &sigbuf[BPF_ORD], PITCH_FR);
		v_equ_shr(envdel[i], &sigbuf[BPF_ORD + FRAME - ENV_ORD],
				  (Shortword) (-scale), ENV_ORD);

		/* Scale signal for pitch correlations */
		f_pitch_scale(&sigbuf[BPF_ORD], &sigbuf[BPF_ORD], PITCH_FR);

		/* Check correlations for each frame */
		temp = frac_pch(&sigbuf[BPF_ORD + PITCHMAX], &pcorr, *pitch, 0,
						PITCHMIN, PITCHMAX, PITCHMIN_Q7, PITCHMAX_Q7,
						MINLENGTH);

		/* reduce envelope correlation */
		pcorr = sub(pcorr, X01_Q14);

		if (pcorr > bpvc[i])
			bpvc[i] = pcorr;
	}
}


/* Name: dc_rmv.c                                                             */
/*	Description: remove DC from input signal                                  */
/*	Inputs:                                                                   */
/*	  sigin[] - input signal                                                  */
/*	  dcdel[] - filter delay history (size DC_ORD)                            */
/*	  frame - number of samples to filter                                     */
/*	Outputs:                                                                  */
/*	  sigout[] - output signal                                                */
/*	  dcdel[] - updated filter delay history                                  */
/*	Returns: void                                                             */
/*                                                                            */
/*	Copyright (c) 1995,1997 by Texas Instruments, Inc.	All rights reserved.  */

/* DC removal filter                                                          */
/* 4th order Chebychev Type II 60 Hz removal filter                           */
/* cutoff = 60 Hz, stop = -30 dB                                              */
/* matlab commands: [z, p, k] = cheby2(4, 30, 0.015, 'high');                 */
/*						sos = zp2sos(z, p, k);                                */
/* order of sections swapped                                                  */

void dc_rmv(Shortword sigin[], Shortword sigout[], Shortword delin[],
			Shortword delout_hi[], Shortword delout_lo[],
			Shortword frame)
{
	static const Shortword	dc_num[(DC_ORD/2)*3] = {             /* Maybe Q13 */
#if NEW_DC_FILTER
		8192,  -16376, 8192,
		8192,  -16370, 8192,
		7353,  -14706, 7353
#else
		7769, -15534, 7769,
		8007, -15999, 8007
#endif
	};

	/* Signs of coefficients for dc_den are reversed.  dc_den[0] and          */
	/* dc_den[3] are ignored.                                                 */
	static const Shortword	dc_den[(DC_ORD/2)*3] = {
#if NEW_DC_FILTER
		-8192, 15729, -7569,
		-8192, 16111, -7959,
		-8192, 15520, -7353
#else
		-8192, 15521, -7358,
		-8192, 15986, -7836
#endif
	};
	register Shortword	section;

	/* Remove DC from input speech */
	v_equ(sigout, sigin, frame);
	for (section = 0; section < DC_ORD/2; section++)
		iir_2nd_d(sigout, &dc_den[section*3], &dc_num[section*3], sigout,
				  &delin[section*2], &delout_hi[section*2],
				  &delout_lo[section*2], frame);
}


/* This function removes the DC component of a given signal sigin[].  It      */
/* computes the offset Sum(sigin[])/len by                                    */
/* Sum(sigin[])/len = Sum(sigin[])/2^up_shift * (two_power_down/len) * 2      */
/* where two_power_down <= len < 2^up_shift.  This way we ensure that         */
/* Sum(sigin[])/up_shift does not overflow, (two_power_down/len) is a Q15     */
/* and the multiplication by 2 is straightforward.                            */
/*                                                                            */
/* Originally this function was written in such a way that we use a Shortword */
/* for "sum", and it is important to make sure there is no overflow with      */
/* "sum".  However, later it was found a siginificant inaccuracy is           */
/* introduced if we shift all sigin[] by up_shift (losing significant digits) */
/* and then add them.  This means when "len" is large the result could be     */
/* wrong.  Now "sum" is declared a Longword and all these problems disappear. */

void remove_dc(Shortword sigin[], Shortword sigout[], Shortword len)
{
	register Shortword	i;
	Shortword	up_shift, two_power_down;
	Longword	sum;
	Shortword	temp;
	Shortword	offset;


	/* Find up_shift and two_power_down.  Note that two_power_down can be     */
	/* equal to len.                                                          */

	temp = norm_s(len);
	up_shift = sub(15, temp);
	temp = sub(up_shift, 1);
	two_power_down = shl(1, temp);

	sum = 0;
	for (i = 0; i < len; i++)
		sum = L_add(sum, L_deposit_l(sigin[i]));
	sum = L_shr(sum, up_shift);

	/* if (len > two_power_down) */
	/* if condition has been removed 'cos it is always true */
	{
		temp = divide_s(two_power_down, len);                          /* Q15 */
		offset = mult(extract_l(sum), temp);
	}
	offset = shl(offset, 1);

	for (i = 0; i < len; i++)
		sigout[i] = sub(sigin[i], offset);
}

⌨️ 快捷键说明

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