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

📄 melp_syn.c

📁 MELPe 1200 bps, fixed point
💻 C
📖 第 1 页 / 共 2 页
字号:
/* ================================================================== */
/*                                                                    */ 
/*    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.

*/

#include "sc1200.h"
#include "mathhalf.h"
#include "macro.h"
#include "lpc_lib.h"
#include "mat_lib.h"
#include "vq_lib.h"
#include "fs_lib.h"
#include "math_lib.h"
#include "constant.h"
#include "global.h"
#include "harm.h"
#include "fsvq_cb.h"
#include "dsp_sub.h"
#include "melp_sub.h"
#include "coeff.h"

#if POSTFILTER
#include "postfilt.h"
#endif

#define INV_LPC_ORD			2979
                               /* ((1.0/(LPC_ORD + 1))*(1<<15) + 0.5) for Q15 */
#define X005_Q19			26214                         /* 0.05 * (1 << 19) */
#define X025_Q15			8192                          /* 0.25 * (1 << 15) */
#define X1_732_Q14			28377                        /* 1.732 * (1 << 14) */
#define X12_Q8				3072                           /* 12.0 * (1 << 8) */
#define X30_Q8				7680                           /* 30.0 * (1 << 8) */
#define TIME_DOMAIN_SYN		FALSE
#define TILT_ORD			1
#define SCALEOVER			10
#define INV_SCALEOVER_Q18	26214              /* ((1.0/SCALEOVER)*(1 << 18)) */
#define PDEL				SCALEOVER

#if (MIX_ORD > DISP_ORD)
#define BEGIN MIX_ORD
#else
#define BEGIN DISP_ORD
#endif

#define ORIGINAL_SYNTH_GAIN		FALSE
#if ORIGINAL_SYNTH_GAIN
#define SYN_GAIN_Q4				16000                    /* (1000.0*(1 << 4)) */
#else
#define SYN_GAIN_Q4				32000
#endif


static struct melp_param	prev_par;
static Shortword	sigsave[PITCHMAX];
static Shortword	syn_begin;
static BOOLEAN	erase;

/* Prototype */

static void		melp_syn(struct melp_param *par, Shortword sp_out[]);

/****************************************************************************
**
** Function:		synthesis
**
** Description: 	The synthesis routine for the sc1200 coder
**
** Arguments:
**
**	melp_param *par ---- output encoded melp parameters
**	Shortword sp_in[] ---- input speech data buffer
**
** Return value:	None
**
*****************************************************************************/
void synthesis(struct melp_param *par, Shortword sp_out[])
{
	register Shortword	i;


	/* Copy previous period of processed speech to output array */
	if (syn_begin > 0){
		if (syn_begin > frameSize){                             /* impossible */
			v_equ(sp_out, sigsave, frameSize);
			/* past end: save remainder in sigsave[0] */
			v_equ(sigsave, &sigsave[frameSize], (Shortword) (syn_begin - frameSize));
		} else
			v_equ(sp_out, sigsave, syn_begin);
	}

	erase = FALSE;                                         /* no erasures yet */

	/* Read and decode channel input buffer. */
	if (rate == RATE2400)
		erase = melp_chn_read(&quant_par, par, &prev_par, chbuf);
#if !SKIP_CHANNEL
	else
		erase = (BOOLEAN) low_rate_chn_read(&quant_par, par, &prev_par);
#endif

	if (rate == RATE2400){
		par->uv_flag = quant_par.uv_flag[0];
		melp_syn(par, sp_out);
	} else {
		for (i = 0; i < NF; i++){
			melp_syn(&par[i], &sp_out[i*FRAME]);
			if ((syn_begin > 0) && (i < NF - 1))
				v_equ(&sp_out[(i + 1)*FRAME], sigsave, syn_begin);
		}
	}
}


/* Name: melp_syn.c                                                           */
/*  Description: MELP synthesis                                               */
/*    This program takes the new parameters for a speech                      */
/*    frame and synthesizes the output speech.  It keeps                      */
/*    an internal record of the previous frame parameters                     */
/*    to use for interpolation.                                               */
/*  Inputs:                                                                   */
/*    *par - MELP parameter structure                                         */
/*  Outputs:                                                                  */
/*    speech[] - output speech signal                                         */
/*  Returns: void                                                             */

static void		melp_syn(struct melp_param *par, Shortword sp_out[])
{
	register Shortword	i;
	static BOOLEAN	firstTime = TRUE;
	static Shortword	noise_gain = MIN_NOISE_Q8;
	static Shortword	prev_lpc_gain = ONE_Q15;
	static Shortword	lpc_del[LPC_ORD];                               /* Q0 */
	static Shortword	prev_tilt;
	static Shortword	prev_pcof[MIX_ORD + 1], prev_ncof[MIX_ORD + 1];
	static Shortword	disp_del[DISP_ORD];
	static Shortword	ase_del[LPC_ORD], tilt_del[TILT_ORD];
	static Shortword	pulse_del[MIX_ORD], noise_del[MIX_ORD];
	Shortword	fs_real[PITCHMAX];
	Shortword	sig2[BEGIN + PITCHMAX];
	Shortword	sigbuf[BEGIN + PITCHMAX];
	Shortword	gaincnt, length;
	Shortword	intfact, intfact1, ifact, ifact_gain;
	Shortword	gain, pulse_gain, pitch, jitter;
	Shortword	curr_tilt, tilt_cof[TILT_ORD + 1];
	Shortword	sig_prob, syn_gain, lpc_gain;
	Shortword	lsf[LPC_ORD];
	Shortword	lpc[LPC_ORD + 1];
	Shortword	ase_num[LPC_ORD + 1], ase_den[LPC_ORD];
	Shortword	curr_pcof[MIX_ORD + 1], curr_ncof[MIX_ORD + 1];
	Shortword	pulse_cof[MIX_ORD + 1], noise_cof[MIX_ORD + 1];
	Shortword	temp1, temp2;
	Longword	L_temp1, L_temp2;
	Shortword	fc_prev, fc_curr, fc;

	/* Update adaptive noise level estimate based on last gain */
	if (firstTime){
		noise_gain = par->gain[NUM_GAINFR - 1];           /* noise_gain in Q8 */
		prev_tilt = 0;
		v_zap(prev_pcof, MIX_ORD + 1);
		v_zap(prev_ncof, MIX_ORD + 1);
		prev_ncof[MIX_ORD/2] = ONE_Q15;
		v_zap(disp_del, DISP_ORD);
		v_zap(ase_del, LPC_ORD);
		v_zap(tilt_del, TILT_ORD);
		v_zap(pulse_del, MIX_ORD);
		v_zap(noise_del, MIX_ORD);
		firstTime = FALSE;
	} else if (!erase){
		for (i = 0; i < NUM_GAINFR; i++){
			noise_est(par->gain[i], &noise_gain, UPCONST_Q19, DOWNCONST_Q17,
					  MIN_NOISE_Q8, MAX_NOISE_Q8);

			/* Adjust gain based on noise level (noise suppression) */
			noise_sup(&par->gain[i], noise_gain, MAX_NS_SUP_Q8, MAX_NS_ATT_Q8,
					  NFACT_Q8);
		}
	}

	if (par->uv_flag && (rate == RATE1200)){
		fill(par->fs_mag, ONE_Q13, NUM_HARM);
		par->pitch = UV_PITCH_Q7;
		par->jitter = X025_Q15;
	}

	/* Un-weight Fourier magnitudes */
	if (!par->uv_flag && !erase)
		window_Q(par->fs_mag, w_fs_inv, par->fs_mag, NUM_HARM, 14);

	/* Clamp LSP bandwidths to avoid sharp LPC filters */
	lpc_clamp(par->lsf, BWMIN_Q15, LPC_ORD);

	/* Calculate spectral tilt for current frame for spectral enhancement */
	tilt_cof[0] = ONE_Q15;                                 /* tilt_cof in Q15 */
	lpc_lsp2pred(par->lsf, &(lpc[1]), LPC_ORD);

	/* Use LPC prediction gain for adaptive scaling */

	/*	lpc_gain = sqrt(lpc_pred2refl(lpc, sig2, LPC_ORD)); */
	/* Here we only make use of sig2[0] from the returned value instead of    */
	/* using the whole array sig2[].                                          */

	lpc_gain = lpc_pred2refl(&(lpc[1]), sig2, LPC_ORD);
	lpc_gain = sqrt_fxp(lpc_gain, 15);                     /* lpc_gain in Q15 */
	if (sig2[0] < 0)
		curr_tilt = shr(sig2[0], 1);                      /* curr_tilt in Q15 */
	else
		curr_tilt = 0;

	/* Disable pitch interpolation for high-pitched onsets */

	/*	if (par->pitch < 0.5*prev_par.pitch &&
		par->gain[0] > 6.0 + prev_par.gain[NUM_GAINFR - 1]) */

	temp1 = shr(prev_par.pitch, 1);
	temp2 = add(SIX_Q8, prev_par.gain[NUM_GAINFR - 1]);
	if ((par->pitch < temp1) && (par->gain[0] > temp2)){
		/* copy current pitch into previous */
		prev_par.pitch = par->pitch;
	}

	/* Set pulse and noise coefficients based on voicing strengths */
	v_zap(curr_pcof, MIX_ORD + 1);                        /* curr_pcof in Q14 */
	v_zap(curr_ncof, MIX_ORD + 1);                        /* curr_ncof in Q14 */
	for (i = 0; i < NUM_BANDS; i++){
		if (par->bpvc[i] > X05_Q14)
			v_add(curr_pcof, bp_cof[i], MIX_ORD + 1);    /* bp_cof in Q14 */
		else
			v_add(curr_ncof, bp_cof[i], MIX_ORD + 1);
	}

	/* Process each pitch period */
	while (syn_begin < FRAME){

		/* interpolate previous and current parameters */

⌨️ 快捷键说明

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