melp_syn.c
资源名称:melp.rar [点击查看]
上传用户:csczyc
上传日期:2021-02-19
资源大小:1051k
文件大小:23k
源码类别:
语音压缩
开发平台:
C/C++
- /*
- 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.
- */
- /*
- 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
- */
- /* compiler include files */
- #include <stdio.h>
- #include <math.h>
- #include "mathhalf.h"
- #include "melp.h"
- #include "spbstd.h"
- #include "lpc.h"
- #include "mat.h"
- #include "vq.h"
- #include "fs.h"
- #include "math_lib.h"
- #include "constant.h"
- #include "wmops.h"
- /* compiler constants */
- #define ORIGINAL_SYNTH_GAIN 0
- #if (MIX_ORD > DISP_ORD)
- #define BEGIN MIX_ORD
- #else
- #define BEGIN DISP_ORD
- #endif
- #define TILT_ORD 1
- #if (ORIGINAL_SYNTH_GAIN)
- #define SYN_GAIN_Q4 16000 /* (1000.0*(1<<4)) */
- #else
- #define SYN_GAIN_Q4 32000 /* (2000.0*(1<<4)) */
- #endif
- #define SCALEOVER 10
- #define INV_SCALEOVER_Q18 26214 /* ((1.0/SCALEOVER)*(1<<18)) */
- #define PDEL SCALEOVER
- /* external memory references */
- extern Shortword bp_cof[NUM_BANDS][MIX_ORD+1];
- extern Shortword disp_cof[DISP_ORD+1];
- extern Shortword msvq_cb[];
- extern Shortword msvq_cb_mean[];
- extern Shortword fsvq_cb[];
- extern Shortword fsvq_weighted;
- extern FILE *fp_indat, *fp_outdat;
- /* temporary memory */
- static Shortword sigbuf[BEGIN+PITCHMAX];
- static Shortword sig2[BEGIN+PITCHMAX];
- static Shortword fs_real[PITCHMAX];
- static Shortword sp_out[BEGIN+FRAME];
- /* permanent memory */
- static Shortword firstcall = 1; /* Just used for noise gain init */
- static Shortword prev_gain_err;
- static Shortword sigsave[PITCHMAX];
- static struct melp_param prev_par;
- static Shortword syn_begin;
- static Shortword prev_scale;
- static Shortword noise_gain = (Shortword)MIN_NOISE_Q8;
- static Shortword pulse_del[MIX_ORD],noise_del[MIX_ORD];
- static Shortword lpc_del[LPC_ORD],ase_del[LPC_ORD],tilt_del[TILT_ORD];
- static Shortword disp_del[DISP_ORD];
- static Shortword prev_lpc_gain;
- static struct msvq_param vq_par; /* MSVQ parameters */
- static struct msvq_param fs_vq_par; /* Fourier series VQ parameters */
- static Shortword w_fs_inv[NUM_HARM];
- /* these can be saved or recomputed */
- static Shortword prev_pcof[MIX_ORD+1],prev_ncof[MIX_ORD+1];
- static Shortword prev_tilt;
- //static Shortword prev_gain;
- /*static Shortword frame=0;*/
- void melp_syn(struct melp_param *par,Shortword speech_out[])
- {
- Shortword i, gaincnt;
- Shortword erase;
- Shortword 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+1];
- Shortword lpc[LPC_ORD+1];
- Shortword ase_num[LPC_ORD+1],ase_den[LPC_ORD+1];
- 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;
- Longword L_temp3,L_temp4;
- Shortword swRnd;
- /* Copy previous period of processed speech to output array */
- if (syn_begin > 0) {
- if (syn_begin > FRAME) {
- v_equ(&sp_out[BEGIN],&sigsave[0],FRAME);
- /* past end: save remainder in sigsave[0] */
- v_equ(&sigsave[0],&sigsave[FRAME],(Shortword)(syn_begin-FRAME));
- }
- else
- v_equ(&sp_out[BEGIN],&sigsave[0],syn_begin);
- }
- erase = 0; /* no erasures yet */
- /* Update MSVQ information */
- par->msvq_stages = vq_par.num_stages;
- par->msvq_bits = vq_par.num_bits;
- par->msvq_levels = vq_par.num_levels;
- par->msvq_index = vq_par.indices;
- par->fsvq_index = fs_vq_par.indices;
- /* Read and decode channel input buffer */
- erase = melp_chn_read(par,&prev_par);
- if (par->uv_flag != 1 && !erase) {
- /* Un-weight Fourier magnitudes */
- window_Q(&par->fs_mag[0],w_fs_inv,&par->fs_mag[0],NUM_HARM,14);
- }
- /* Update adaptive noise level estimate based on last gain */
- if (firstcall) {
- firstcall = 0;
- noise_gain = par->gain[NUM_GAINFR-1]; /* noise_gain in Q8 */
- }
- else if (!erase) {
- for (i = 0; i < NUM_GAINFR; i++) {
- noise_est(par->gain[i],&noise_gain,(Shortword)UPCONST_Q19,
- (Shortword)DOWNCONST_Q17,(Shortword)MIN_NOISE_Q8,
- (Shortword)MAX_NOISE_Q8);
- /* Adjust gain based on noise level (noise suppression) */
- noise_sup(&par->gain[i],noise_gain,(Shortword)MAX_NS_SUP_Q8,
- (Shortword)MAX_NS_ATT_Q8,(Shortword)NFACT_Q8);
- }
- }
- /* 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,LPC_ORD);
- #if (!ORIGINAL_SYNTH_GAIN)
- /* Use LPC prediction gain for adaptive scaling */
- /* lpc_gain = sqrt(lpc_pred2refl(lpc,sig2,LPC_ORD));*/
- lpc_gain = lpc_pred2refl(lpc,sig2,LPC_ORD);
- lpc_gain = sqrt_fxp(lpc_gain,15); /* lpc_gain in Q15 */
- #else
- /* Original synthesis scaling */
- lpc_pred2refl(lpc,sig2,LPC_ORD);
- lpc_gain = ONE_Q15;
- #endif
- if (sig2[1] < 0)
- curr_tilt = shr_a(sig2[1],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_a(prev_par.pitch,1);
- temp2 = (Shortword)SIX_Q8 + prev_par.gain[NUM_GAINFR-1];
- // compare_nonzero(); compare_nonzero();mark del
- 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][0],MIX_ORD+1); /* bp_cof in Q14 */
- else
- v_add(curr_ncof,&bp_cof[i][0],MIX_ORD+1);
- }
- /* Process each pitch period */
- while (syn_begin < FRAME) {
- /* interpolate previous and current parameters */
- ifact = divide_s(syn_begin,FRAME); /* ifact in Q15 */
- if (syn_begin >= GAINFR) {
- gaincnt = 2;
- temp1 = sub(syn_begin,GAINFR);
- ifact_gain = divide_s(temp1,GAINFR);
- }
- else {
- gaincnt = 1;
- ifact_gain = divide_s(syn_begin,GAINFR);
- }
- /* interpolate gain */
- if (gaincnt > 1) {
- /* gain = ifact_gain*par->gain[gaincnt-1] +
- (1.0-ifact_gain)*par->gain[gaincnt-2]; */
- /* L_temp1 = L_mult(par->gain[gaincnt-1],ifact_gain); */
- /* temp1 = sub(ONE_Q15,ifact_gain); */
- /* L_temp2 = L_mult(par->gain[gaincnt-2],temp1); */
- /* gain = extract_h(L_add(L_temp1,L_temp2)); gain in Q8 */
- L_temp1 = _smpy(par->gain[gaincnt-1],ifact_gain);
- temp1 = sub(ONE_Q15,ifact_gain);
- L_temp2 = _smpy(par->gain[gaincnt-2],temp1);
- L_temp3 = _sadd(L_temp1,L_temp2);
- gain = (Shortword) (0x0000ffffL & (L_temp3 >> 16));
- }
- else {
- /* gain = ifact_gain*par->gain[gaincnt-1] +
- (1.0-ifact_gain)*prev_par.gain[NUM_GAINFR-1]; */
- /* L_temp1 = L_mult(par->gain[gaincnt-1],ifact_gain); */
- /* temp1 = sub(ONE_Q15,ifact_gain); */
- /* L_temp2 = L_mult(prev_par.gain[NUM_GAINFR-1],temp1); */
- /* gain = extract_h(L_add(L_temp1,L_temp2)); gain in Q8 */
- L_temp1 = _smpy(par->gain[gaincnt-1],ifact_gain);
- temp1 = sub(ONE_Q15,ifact_gain);
- L_temp2 = _smpy(prev_par.gain[NUM_GAINFR-1],temp1);
- L_temp3 = _sadd(L_temp1,L_temp2);
- gain = (Shortword) (0x0000ffffL & (L_temp3 >> 16));
- }
- /* Set overall interpolation path based on gain change */
- temp1 = sub(par->gain[NUM_GAINFR-1],prev_par.gain[NUM_GAINFR-1]);
- // compare_nonzero();mark del
- if (abs_s(temp1) > SIX_Q8) {
- /* Power surge: use gain adjusted interpolation */
- /* intfact = (gain - prev_par.gain[NUM_GAINFR-1]) / temp; */
- temp2 = sub(gain,prev_par.gain[NUM_GAINFR-1]);
- if (((temp2 > 0) && (temp1 < 0)) || ((temp2 < 0) && (temp1 > 0)))
- intfact = 0;
- else {
- /* temp1 = abs_s(temp1); */
- /* temp2 = abs_s(temp2); */
- L_temp3 = _abs2((Longword)temp1);
- temp1 = (Shortword) (0x0000ffffL & L_temp3);
- L_temp3 = _abs2((Longword)temp2);
- temp2 = (Shortword) (0x0000ffffL & L_temp3);
- if (temp2 >= temp1)
- intfact = ONE_Q15;
- else
- intfact = divide_s(temp2,temp1); /* intfact in Q15 */
- }
- }
- else
- /* Otherwise, linear interpolation */
- intfact = ifact;
- /* interpolate LSF's and convert to LPC filter */
- interp_array(prev_par.lsf,par->lsf,lsf,intfact,LPC_ORD+1);
- lpc_lsp2pred(lsf,lpc,LPC_ORD);
- /* Check signal probability for adaptive spectral enhancement filter */
- /* temp1 = add(noise_gain,(Shortword)X12_Q8); */
- /* temp2 = add(noise_gain,(Shortword)X30_Q8); */
- L_temp3 = _sadd2((Longword)noise_gain,(Longword)X12_Q8);
- temp1 = (Shortword) (0x0000ffffL & L_temp3);
- L_temp4 = _sadd2((Longword)noise_gain,(Longword)X30_Q8);
- temp2 = (Shortword) (0x0000ffffL & L_temp4);
- /* sig_prob in Q15 */
- sig_prob = lin_int_bnd(gain,temp1,temp2,0,ONE_Q15);
- /* Calculate adaptive spectral enhancement filter coefficients */
- ase_num[0] = ONE_Q12; /* ase_num and ase_den in Q12 */
- /* temp1 = mult(sig_prob,(Shortword)ASE_NUM_BW_Q15); */
- L_temp3 = _smpy(sig_prob,(Shortword)ASE_NUM_BW_Q15);
- temp1 = (Shortword) (0x0000ffffL & (L_temp3 >> 16));
- lpc_bw_expand(lpc,ase_num,temp1,LPC_ORD);
- /* temp1 = mult(sig_prob,(Shortword)ASE_DEN_BW_Q15); */
- L_temp4 = _smpy(sig_prob,(Shortword)ASE_DEN_BW_Q15);
- temp1 = (Shortword) (0x0000ffffL & (L_temp4 >> 16));
- lpc_bw_expand(lpc,ase_den,temp1,LPC_ORD);
- /* tilt_cof[1] = sig_prob*(intfact*curr_tilt +
- (1.0-intfact)*prev_tilt); */
- /* temp1 = mult(curr_tilt,intfact); */
- /* intfact1 = sub(ONE_Q15,intfact); */
- /* temp2 = mult(prev_tilt,intfact1); */
- /* temp1 = add(temp1,temp2); */
- /* tilt_cof[1] = mult(sig_prob,temp1); tilt_cof in Q15 */
- L_temp3 = _smpy(curr_tilt,intfact);
- temp1 = (Shortword) (0x0000ffffL & (L_temp3 >> 16));
- intfact1 = sub(ONE_Q15,intfact);
- L_temp4 = _smpy(prev_tilt,intfact1);
- temp2 = (Shortword) (0x0000ffffL & (L_temp4 >> 16));
- L_temp3 = _sadd2((Longword)temp1,(Longword)temp2);
- temp1 = (Shortword) (0x0000ffffL & L_temp3);
- L_temp4 = _smpy(sig_prob,temp1);
- tilt_cof[1] = (Shortword) (0x0000ffffL & (L_temp4 >> 16));
- /* interpolate pitch and pulse gain */
- /* syn_gain = SYN_GAIN*(intfact*lpc_gain +
- (1.0-intfact)*prev_lpc_gain); */
- /* temp1 = mult(lpc_gain,intfact); lpc_gain in Q15 */
- /* temp2 = mult(prev_lpc_gain,intfact1); */
- /* temp1 = add(temp1,temp2); temp1 in Q15 */
- /* syn_gain = mult((Shortword)SYN_GAIN_Q4,temp1); syn_gain in Q4 */
- L_temp3 = _smpy(lpc_gain,intfact);
- temp1 = (Shortword) (0x0000ffffL & (L_temp3 >> 16));
- L_temp4 = _smpy(prev_lpc_gain,intfact1);
- temp2 = (Shortword) (0x0000ffffL & (L_temp4 >> 16));
- L_temp3 = _sadd2((Longword)temp1,(Longword)temp2);
- temp1 = (Shortword) (0x0000ffffL & L_temp3);
- L_temp4 = _smpy((Shortword)SYN_GAIN_Q4,temp1);
- syn_gain = (Shortword) (0x0000ffffL & (L_temp4 >> 16));
- /* pitch = intfact*par->pitch + (1.0-intfact)*prev_par.pitch; */
- /* temp1 = mult(par->pitch,intfact); */
- /* temp2 = mult(prev_par.pitch,intfact1); */
- /* pitch = add(temp1,temp2); pitch in Q7 */
- L_temp3 = _smpy(par->pitch,intfact);
- temp1 = (Shortword) (0x0000ffffL & (L_temp3 >> 16));
- L_temp4 = _smpy(prev_par.pitch,intfact1);
- temp2 = (Shortword) (0x0000ffffL & (L_temp4 >> 16));
- L_temp3 = _sadd2((Longword)temp1,(Longword)temp2);
- pitch = (Shortword) (0x0000ffffL & L_temp3);
- /* pulse_gain = syn_gain*sqrt(pitch); */
- temp1 = sqrt_fxp(pitch,7);
- /* L_temp1 = L_mult(syn_gain,temp1); */
- /* L_temp1 = L_shl(L_temp1,4); */
- /* pulse_gain = extract_h(L_temp1); pulse_gain in Q0 */
- L_temp1 = _smpy(syn_gain,temp1);
- L_temp1 = _sshl(L_temp1,4);
- pulse_gain = (Shortword) (0x0000ffffL & (L_temp1 >> 16));
- /* interpolate pulse and noise coefficients */
- temp1 = sqrt_fxp(ifact,15);
- interp_array(prev_pcof,curr_pcof,pulse_cof,temp1,MIX_ORD+1);
- interp_array(prev_ncof,curr_ncof,noise_cof,temp1,MIX_ORD+1);
- /* interpolate jitter */
- /* jitter = ifact*par->jitter + (1.0-ifact)*prev_par.jitter; */
- /* temp1 = mult(par->jitter,ifact); */
- /* temp2 = sub(ONE_Q15,ifact); */
- /* temp2 = mult(prev_par.jitter,temp2); */
- /* jitter = add(temp1,temp2); */
- L_temp3 = _smpy(par->jitter,ifact);
- temp1 = (Shortword) (0x0000ffffL & (L_temp3 >> 16));
- temp2 = sub(ONE_Q15,ifact);
- L_temp4 = _smpy(prev_par.jitter,temp2);
- temp2 = (Shortword) (0x0000ffffL & (L_temp4 >> 16));
- L_temp3 = _sadd2((Longword)temp1,(Longword)temp2);
- jitter = (Shortword) (0x0000ffffL & L_temp3);
- /* scale gain by 0.05 but keep gain in log */
- /* gain = pow(10.0,0.05*gain); */
- /* gain = mult((Shortword)X005_Q19,gain); gain in Q12 */
- L_temp3 = _smpy((Shortword)X005_Q19,gain);
- gain = (Shortword) (0x0000ffffL & (L_temp3 >> 16));
- /* Set period length based on pitch and jitter */
- rand_num(&temp1,ONE_Q15,1);
- /* length = pitch * (1.0-jitter*temp) + 0.5; */
- /* temp1 = mult(jitter,temp1); */
- /* temp1 = shr(temp1,1); temp1 in Q14 */
- /* temp1 = sub(ONE_Q14,temp1); */
- /* temp1 = mult(pitch,temp1); length in Q6 */
- L_temp3 = _smpy(jitter,temp1);
- L_temp3 = _shr2(L_temp3,1);
- temp1 = (Shortword) (0x0000ffffL & (L_temp3 >> 16));
- temp1 = sub(ONE_Q14,temp1);
- L_temp4 = _smpy(pitch,temp1);
- temp1 = (Shortword) (0x0000ffffL & (L_temp4 >> 16));
- /* length = shift_r(temp1,-6); length in Q0 with rounding */
- L_temp3 = _shr2((Longword)temp1,5);
- swRnd = (Shortword) (0x0000ffffL & L_temp3);
- swRnd = (Shortword) (swRnd & (Shortword)0x1);
- L_temp4 = _shr2((Longword)temp1,6);
- L_temp3 = _sadd2(L_temp4,(Longword)swRnd);
- length = (Shortword) (0x0000ffffL & L_temp3);
- // compare_nonzero();mark del
- if (length < PITCHMIN)
- length = PITCHMIN;
- // compare_nonzero();mark del
- if (length > PITCHMAX)
- length = PITCHMAX;
- /* Use inverse DFT for pulse excitation */
- fill(fs_real,ONE_Q13,length);
- fs_real[0] = 0;
- interp_array(prev_par.fs_mag,par->fs_mag,&fs_real[1],intfact,
- NUM_HARM);
- idft_real(fs_real,&sigbuf[BEGIN],length); /* sigbuf in Q15 */
- /* Delay overall signal by PDEL samples (circular shift) */
- /* use fs_real as a scratch buffer */
- v_equ(fs_real,&sigbuf[BEGIN],length);
- v_equ(&sigbuf[BEGIN+PDEL],fs_real,(Shortword)(length-PDEL));
- v_equ(&sigbuf[BEGIN],&fs_real[length-PDEL],PDEL);
- /* Scale by pulse gain */
- v_scale(&sigbuf[BEGIN],pulse_gain,length); /* sigbuf in Q0 */
- /* Filter and scale pulse excitation */
- v_equ(&sigbuf[BEGIN-MIX_ORD],pulse_del,MIX_ORD);
- v_equ(pulse_del,&sigbuf[length+BEGIN-MIX_ORD],MIX_ORD);
- zerflt_Q(&sigbuf[BEGIN],pulse_cof,&sigbuf[BEGIN],MIX_ORD,length,14);
- /* Get scaled noise excitation */
- /* temp1 = shr(mult((Shortword)X1_732_Q14,syn_gain),3); temp1 in Q0 */
- L_temp3 = _smpy((Shortword)X1_732_Q14,syn_gain);
- L_temp3 = _shr2(L_temp3,3);
- temp1 = (Shortword) (0x0000ffffL & (L_temp3 >> 16));
- rand_num(&sig2[BEGIN],temp1,length); /* sig2 in Q0 */
- /* Filter noise excitation */
- v_equ(&sig2[BEGIN-MIX_ORD],noise_del,MIX_ORD);
- v_equ(noise_del,&sig2[length+BEGIN-MIX_ORD],MIX_ORD);
- zerflt_Q(&sig2[BEGIN],noise_cof,&sig2[BEGIN],MIX_ORD,length,14);
- /* Add two excitation signals (mixed excitation) */
- v_add(&sigbuf[BEGIN],&sig2[BEGIN],length); /* sigbuf in Q0 */
- /* Adaptive spectral enhancement */
- v_equ(&sigbuf[BEGIN-LPC_ORD],ase_del,LPC_ORD);
- lpc_synthesis(&sigbuf[BEGIN],&sigbuf[BEGIN],ase_den,LPC_ORD,length);
- v_equ(ase_del,&sigbuf[BEGIN+length-LPC_ORD],LPC_ORD);
- zerflt(&sigbuf[BEGIN],ase_num,&sigbuf[BEGIN],LPC_ORD,length);
- v_equ(&sigbuf[BEGIN-TILT_ORD],tilt_del,TILT_ORD);
- v_equ(tilt_del,&sigbuf[length+BEGIN-TILT_ORD],TILT_ORD);
- zerflt_Q(&sigbuf[BEGIN],tilt_cof,&sigbuf[BEGIN],TILT_ORD,length,15);
- /* Perform LPC synthesis filtering */
- v_equ(&sigbuf[BEGIN-LPC_ORD],lpc_del,LPC_ORD);
- lpc_synthesis(&sigbuf[BEGIN],&sigbuf[BEGIN],lpc,LPC_ORD,length);
- v_equ(lpc_del,&sigbuf[length+BEGIN-LPC_ORD],LPC_ORD);
- /* Adjust scaling of synthetic speech */
- /* sigbuf in Q0 */
- scale_adj(&sigbuf[BEGIN],gain,&prev_scale,length,
- SCALEOVER,(Shortword)INV_SCALEOVER_Q18);
- /* Copy processed speech to output array (not past frame end) */
- // compare_nonzero();mark del
- if (add(syn_begin,length) > FRAME) {
- v_equ(&sp_out[BEGIN+syn_begin],&sigbuf[BEGIN],
- (Shortword)(FRAME-syn_begin));
- /* past end: save remainder in sigsave[0] */
- v_equ(&sigsave[0],&sigbuf[BEGIN+FRAME-syn_begin],
- (Shortword)(length-(FRAME-syn_begin)));
- }
- else
- v_equ(&sp_out[BEGIN+syn_begin],&sigbuf[BEGIN],length);
- /* Update syn_begin for next period */
- syn_begin = add(syn_begin,length);
- }
- /* Implement pulse dispersion filter on output speech */
- v_equ(&sp_out[BEGIN-DISP_ORD],disp_del,DISP_ORD);
- v_equ(disp_del,&sp_out[FRAME+BEGIN-DISP_ORD],DISP_ORD);
- zerflt_Q(&sp_out[BEGIN],disp_cof,speech_out,DISP_ORD,FRAME,15);
- /* Save previous pulse and noise filters for next frame */
- v_equ(prev_pcof,curr_pcof,MIX_ORD+1);
- v_equ(prev_ncof,curr_ncof,MIX_ORD+1);
- /* Copy current parameters to previous parameters for next time */
- prev_par = *par;
- prev_tilt = curr_tilt;
- prev_lpc_gain = lpc_gain;
- /* Update syn_begin for next frame */
- syn_begin = sub(syn_begin,FRAME);
- //#if (COMPLEXITY_COUNT) mark del
- //complexity_count();
- //#endif
- }
- /*
- *
- * Subroutine melp_syn_init(): perform initialization for melp
- * synthesis
- *
- */
- #define INV_LPC_ORD 2979 /* ((1.0/(LPC_ORD+1))*(1<<15)+0.5) */
- void melp_syn_init()
- {
- Shortword i;
- Shortword w_fs[NUM_HARM];
- Longword L_temp;
- v_zap(prev_par.gain,NUM_GAINFR);
- prev_par.pitch = UV_PITCH_Q7;
- prev_par.lsf[0] = 0;
- for (i = 1; i < LPC_ORD+1; i++){
- /* prev_par.lsf[i] = add(prev_par.lsf[i-1],(Shortword)INV_LPC_ORD); */
- L_temp = _sadd2((Longword)prev_par.lsf[i-1],(Longword)INV_LPC_ORD);
- prev_par.lsf[i] = (Shortword) (0x0000ffffL & L_temp);
- }
- prev_par.jitter = 0;
- v_zap(&prev_par.bpvc[0],NUM_BANDS);
- prev_tilt=0;
- // prev_gain = 0;
- prev_scale = 0;
- prev_lpc_gain = ONE_Q15;
- syn_begin = 0;
- noise_gain = (Shortword)MIN_NOISE_Q8;
- firstcall = 1;
- prev_gain_err = 0;
- v_zap(pulse_del,MIX_ORD);
- v_zap(noise_del,MIX_ORD);
- v_zap(lpc_del,LPC_ORD);
- v_zap(ase_del,LPC_ORD);
- v_zap(tilt_del,TILT_ORD);
- v_zap(disp_del,DISP_ORD);
- v_zap(sig2,BEGIN+PITCHMAX);
- v_zap(sigbuf,BEGIN+PITCHMAX);
- v_zap(sigsave,PITCHMAX);
- v_zap(prev_pcof,MIX_ORD+1);
- v_zap(prev_ncof,MIX_ORD+1);
- prev_ncof[MIX_ORD/2] = ONE_Q15;
- fill(prev_par.fs_mag,ONE_Q13,NUM_HARM);
- /*
- * Initialize multi-stage vector quantization (read codebook)
- */
- vq_par.num_best = MSVQ_M;
- vq_par.num_stages = 4;
- vq_par.dimension = 10;
- /*
- * Allocate memory for number of levels per stage and indices
- * and for number of bits per stage
- */
- MEM_ALLOC(MALLOC,vq_par.num_levels,vq_par.num_stages,Shortword);
- MEM_ALLOC(MALLOC,vq_par.indices,vq_par.num_stages,Shortword);
- MEM_ALLOC(MALLOC,vq_par.num_bits,vq_par.num_stages,Shortword);
- vq_par.num_levels[0] = 128;
- vq_par.num_levels[1] = 64;
- vq_par.num_levels[2] = 64;
- vq_par.num_levels[3] = 64;
- vq_par.num_bits[0] = 7;
- vq_par.num_bits[1] = 6;
- vq_par.num_bits[2] = 6;
- vq_par.num_bits[3] = 6;
- vq_par.cb = msvq_cb;
- vq_par.cb_mean = msvq_cb_mean;
- /*
- * Initialize Fourier magnitude vector quantization (read codebook)
- */
- fs_vq_par.num_best = 1;
- fs_vq_par.num_stages = 1;
- fs_vq_par.dimension = NUM_HARM;
- /*
- * Allocate memory for number of levels per stage and indices
- * and for number of bits per stage
- */
- MEM_ALLOC(MALLOC,fs_vq_par.num_levels,fs_vq_par.num_stages,Shortword);
- MEM_ALLOC(MALLOC,fs_vq_par.indices,fs_vq_par.num_stages,Shortword);
- MEM_ALLOC(MALLOC,fs_vq_par.num_bits,fs_vq_par.num_stages,Shortword);
- fs_vq_par.num_levels[0] = FS_LEVELS;
- fs_vq_par.num_bits[0] = FS_BITS;
- fs_vq_par.cb = fsvq_cb;
- /*
- * Initialize fixed MSE weighting and inverse of weighting
- */
- vq_fsw(w_fs, NUM_HARM, (Shortword)X60_Q9);
- for (i = 0; i < NUM_HARM; i++)
- w_fs_inv[i] = divide_s(ONE_Q13,w_fs[i]); /* w_fs_inv in Q14 */
- /*
- * Pre-weight codebook (assume single stage only)
- */
- if (fsvq_weighted == 0)
- {
- fsvq_weighted = 1;
- for (i = 0; i < fs_vq_par.num_levels[0]; i++)
- window_Q(&fs_vq_par.cb[i*NUM_HARM],w_fs,
- &fs_vq_par.cb[i*NUM_HARM],NUM_HARM,14);
- }
- }