void pitch_unquant_3tap( spx_sig_t exc[], /* Excitation */ int start, /* Smallest pitch value allowed */ int end, /* Largest pitch value allowed */ spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */ const void *par, int nsf, /* Number of samples in subframe */ int *pitch_val, spx_word16_t *gain_val, SpeexBits *bits, char *stack, int count_lost, int subframe_offset, spx_word16_t last_pitch_gain, int cdbk_offset ) { int i; int pitch; int gain_index; spx_word16_t gain[3]; const signed char *gain_cdbk; int gain_cdbk_size; const ltp_params *params; params = (const ltp_params*) par; gain_cdbk_size = 1<<params->gain_bits; gain_cdbk = params->gain_cdbk + 3*gain_cdbk_size*cdbk_offset; pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits); pitch += start; gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits); /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/ #ifdef FIXED_POINT gain[0] = 32+(spx_word16_t)gain_cdbk[gain_index*3]; gain[1] = 32+(spx_word16_t)gain_cdbk[gain_index*3+1]; gain[2] = 32+(spx_word16_t)gain_cdbk[gain_index*3+2]; #else gain[0] = 0.015625*gain_cdbk[gain_index*3]+.5; gain[1] = 0.015625*gain_cdbk[gain_index*3+1]+.5; gain[2] = 0.015625*gain_cdbk[gain_index*3+2]+.5; #endif if (count_lost && pitch > subframe_offset) { float gain_sum; if (1) { float tmp = count_lost < 4 ? GAIN_SCALING_1*last_pitch_gain : 0.4 * GAIN_SCALING_1 * last_pitch_gain; if (tmp>.95) tmp=.95; gain_sum = GAIN_SCALING_1*gain_3tap_to_1tap(gain); if (gain_sum > tmp) { float fact = tmp/gain_sum; for (i=0; i<3; i++) gain[i]*=fact; } } } *pitch_val = pitch; gain_val[0]=gain[0]; gain_val[1]=gain[1]; gain_val[2]=gain[2]; { spx_sig_t *e[3]; VARDECL(spx_sig_t *tmp2); ALLOC(tmp2, 3*nsf, spx_sig_t); e[0]=tmp2; e[1]=tmp2+nsf; e[2]=tmp2+2*nsf; for (i=0; i<3; i++) { int j; int pp=pitch+1-i; #if 0 for (j=0; j<nsf; j++) { if (j-pp<0) e[i][j]=exc[j-pp]; else if (j-pp-pitch<0) e[i][j]=exc[j-pp-pitch]; else e[i][j]=0; } #else { int tmp1, tmp3; tmp1=nsf; if (tmp1>pp) tmp1=pp; for (j=0; j<tmp1; j++) e[i][j]=exc[j-pp]; tmp3=nsf; if (tmp3>pp+pitch) tmp3=pp+pitch; for (j=tmp1; j<tmp3; j++) e[i][j]=exc[j-pp-pitch]; for (j=tmp3; j<nsf; j++) e[i][j]=0; } #endif } #ifdef FIXED_POINT { for (i=0; i<nsf; i++) exc[i]=SHL32(ADD32(ADD32(MULT16_32_Q15(SHL16(gain[0],7),e[2][i]), MULT16_32_Q15(SHL16(gain[1],7),e[1][i])), MULT16_32_Q15(SHL16(gain[2],7),e[0][i])), 2); } #else for (i=0; i<nsf; i++) exc[i]=VERY_SMALL+gain[0]*e[2][i]+gain[1]*e[1][i]+gain[2]*e[0][i]; #endif } }
void pitch_unquant_3tap( spx_word16_t exc[], /* Input excitation */ spx_word32_t exc_out[], /* Output excitation */ int start, /* Smallest pitch value allowed */ int end, /* Largest pitch value allowed */ spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */ const void* par, int nsf, /* Number of samples in subframe */ int* pitch_val, spx_word16_t* gain_val, SpeexBits* bits, char* stack, int count_lost, int subframe_offset, spx_word16_t last_pitch_gain, int cdbk_offset ) { int i; int pitch; int gain_index; spx_word16_t gain[3]; const signed char* gain_cdbk; int gain_cdbk_size; const ltp_params* params; params = (const ltp_params*) par; gain_cdbk_size = 1 << params->gain_bits; gain_cdbk = params->gain_cdbk + 4 * gain_cdbk_size * cdbk_offset; pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits); pitch += start; gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits); /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/ #ifdef FIXED_POINT gain[0] = ADD16(32, (spx_word16_t)gain_cdbk[gain_index * 4]); gain[1] = ADD16(32, (spx_word16_t)gain_cdbk[gain_index * 4 + 1]); gain[2] = ADD16(32, (spx_word16_t)gain_cdbk[gain_index * 4 + 2]); #else gain[0] = 0.015625 * gain_cdbk[gain_index * 4] + .5; gain[1] = 0.015625 * gain_cdbk[gain_index * 4 + 1] + .5; gain[2] = 0.015625 * gain_cdbk[gain_index * 4 + 2] + .5; #endif if (count_lost && pitch > subframe_offset) { spx_word16_t gain_sum; if (1) { #ifdef FIXED_POINT spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : SHR16(last_pitch_gain, 1); if (tmp > 62) tmp = 62; #else spx_word16_t tmp = count_lost < 4 ? last_pitch_gain : 0.5 * last_pitch_gain; if (tmp > .95) tmp = .95; #endif gain_sum = gain_3tap_to_1tap(gain); if (gain_sum > tmp) { spx_word16_t fact = DIV32_16(SHL32(EXTEND32(tmp), 14), gain_sum); for (i = 0; i < 3; i++) gain[i] = MULT16_16_Q14(fact, gain[i]); } } } *pitch_val = pitch; gain_val[0] = gain[0]; gain_val[1] = gain[1]; gain_val[2] = gain[2]; gain[0] = SHL16(gain[0], 7); gain[1] = SHL16(gain[1], 7); gain[2] = SHL16(gain[2], 7); SPEEX_MEMSET(exc_out, 0, nsf); for (i = 0; i < 3; i++) { int j; int tmp1, tmp3; int pp = pitch + 1 - i; tmp1 = nsf; if (tmp1 > pp) tmp1 = pp; for (j = 0; j < tmp1; j++) exc_out[j] = MAC16_16(exc_out[j], gain[2 - i], exc[j - pp]); tmp3 = nsf; if (tmp3 > pp + pitch) tmp3 = pp + pitch; for (j = tmp1; j < tmp3; j++) exc_out[j] = MAC16_16(exc_out[j], gain[2 - i], exc[j - pp - pitch]); } /*for (i=0;i<nsf;i++) exc[i]=PSHR32(exc32[i],13);*/ }
void comb_filter( spx_sig_t *exc, /*decoded excitation*/ spx_sig_t *new_exc, /*enhanced excitation*/ spx_coef_t *ak, /*LPC filter coefs*/ int p, /*LPC order*/ int nsf, /*sub-frame size*/ int pitch, /*pitch period*/ spx_word16_t *pitch_gain, /*pitch gain (3-tap)*/ spx_word16_t comb_gain, /*gain of comb filter*/ CombFilterMem *mem ) { int i; spx_word16_t exc_energy=0, new_exc_energy=0; spx_word16_t gain; spx_word16_t step; spx_word16_t fact; /*Compute excitation amplitude prior to enhancement*/ exc_energy = compute_rms(exc, nsf); /*for (i=0;i<nsf;i++) exc_energy+=((float)exc[i])*exc[i];*/ /*Some gain adjustment if pitch is too high or if unvoiced*/ #ifdef FIXED_POINT { spx_word16_t g = gain_3tap_to_1tap(pitch_gain)+gain_3tap_to_1tap(mem->last_pitch_gain); if (g > 166) comb_gain = MULT16_16_Q15(DIV32_16(SHL(165,15),g), comb_gain); if (g < 64) comb_gain = MULT16_16_Q15(SHL(g, 9), comb_gain); } #else { float g=0; g = GAIN_SCALING_1*.5*(gain_3tap_to_1tap(pitch_gain)+gain_3tap_to_1tap(mem->last_pitch_gain)); if (g>1.3) comb_gain*=1.3/g; if (g<.5) comb_gain*=2.*g; } #endif step = DIV32(COMB_STEP, nsf); fact=0; /*Apply pitch comb-filter (filter out noise between pitch harmonics)*/ for (i=0;i<nsf;i++) { spx_word32_t exc1, exc2; fact += step; exc1 = SHL(MULT16_32_Q15(SHL(pitch_gain[0],7),exc[i-pitch+1]) + MULT16_32_Q15(SHL(pitch_gain[1],7),exc[i-pitch]) + MULT16_32_Q15(SHL(pitch_gain[2],7),exc[i-pitch-1]) , 2); exc2 = SHL(MULT16_32_Q15(SHL(mem->last_pitch_gain[0],7),exc[i-mem->last_pitch+1]) + MULT16_32_Q15(SHL(mem->last_pitch_gain[1],7),exc[i-mem->last_pitch]) + MULT16_32_Q15(SHL(mem->last_pitch_gain[2],7),exc[i-mem->last_pitch-1]),2); new_exc[i] = exc[i] + MULT16_32_Q15(comb_gain,MULT16_32_Q15(fact,exc1) + MULT16_32_Q15(SUB16(COMB_STEP,fact), exc2)); } mem->last_pitch_gain[0] = pitch_gain[0]; mem->last_pitch_gain[1] = pitch_gain[1]; mem->last_pitch_gain[2] = pitch_gain[2]; mem->last_pitch = pitch; /*Amplitude after enhancement*/ new_exc_energy = compute_rms(new_exc, nsf); if (exc_energy > new_exc_energy) exc_energy = new_exc_energy; gain = DIV32_16(SHL(exc_energy,15),1+new_exc_energy); #ifdef FIXED_POINT if (gain < 16384) gain = 16384; #else if (gain < .5) gain=.5; #endif #ifdef FIXED_POINT for (i=0;i<nsf;i++) { mem->smooth_gain = MULT16_16_Q15(31457,mem->smooth_gain) + MULT16_16_Q15(1311,gain); new_exc[i] = MULT16_32_Q15(mem->smooth_gain, new_exc[i]); } #else for (i=0;i<nsf;i++) { mem->smooth_gain = .96*mem->smooth_gain + .04*gain; new_exc[i] *= mem->smooth_gain; } #endif }