/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */ int pitch_search_3tap( spx_word16_t target[], /* Target vector */ spx_word16_t* sw, spx_coef_t ak[], /* LPCs for this subframe */ spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */ spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */ spx_sig_t exc[], /* Excitation */ const void* par, int start, /* Smallest pitch value allowed */ int end, /* Largest pitch value allowed */ spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */ int p, /* Number of LPC coeffs */ int nsf, /* Number of samples in subframe */ SpeexBits* bits, char* stack, spx_word16_t* exc2, spx_word16_t* r, int complexity, int cdbk_offset, int plc_tuning, spx_word32_t* cumul_gain ) { int i; int cdbk_index, pitch = 0, best_gain_index = 0; VARDECL(spx_sig_t * best_exc); VARDECL(spx_word16_t * new_target); VARDECL(spx_word16_t * best_target); int best_pitch = 0; spx_word32_t err, best_err = -1; int N; const ltp_params* params; const signed char* gain_cdbk; int gain_cdbk_size; int scaledown = 0; VARDECL(int * nbest); params = (const ltp_params*) par; gain_cdbk_size = 1 << params->gain_bits; gain_cdbk = params->gain_cdbk + 4 * gain_cdbk_size * cdbk_offset; N = complexity; if (N > 10) N = 10; if (N < 1) N = 1; ALLOC(nbest, N, int); params = (const ltp_params*) par; if (end < start) { speex_bits_pack(bits, 0, params->pitch_bits); speex_bits_pack(bits, 0, params->gain_bits); SPEEX_MEMSET(exc, 0, nsf); return start; } #ifdef FIXED_POINT /* Check if we need to scale everything down in the pitch search to avoid overflows */ for (i = 0; i < nsf; i++) { if (ABS16(target[i]) > 16383) { scaledown = 1; break; } } for (i = -end; i < nsf; i++) { if (ABS16(exc2[i]) > 16383) { scaledown = 1; break; } } #endif if (N > end - start + 1) N = end - start + 1; if (end != start) open_loop_nbest_pitch(sw, start, end, nsf, nbest, NULL, N, stack); else nbest[0] = start; ALLOC(best_exc, nsf, spx_sig_t); ALLOC(new_target, nsf, spx_word16_t); ALLOC(best_target, nsf, spx_word16_t); for (i = 0; i < N; i++) { pitch = nbest[i]; SPEEX_MEMSET(exc, 0, nsf); err = pitch_gain_search_3tap(target, ak, awk1, awk2, exc, gain_cdbk, gain_cdbk_size, pitch, p, nsf, bits, stack, exc2, r, new_target, &cdbk_index, plc_tuning, *cumul_gain, scaledown); if (err < best_err || best_err < 0) { SPEEX_COPY(best_exc, exc, nsf); SPEEX_COPY(best_target, new_target, nsf); best_err = err; best_pitch = pitch; best_gain_index = cdbk_index; } } /*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/ speex_bits_pack(bits, best_pitch - start, params->pitch_bits); speex_bits_pack(bits, best_gain_index, params->gain_bits); #ifdef FIXED_POINT *cumul_gain = MULT16_32_Q13(SHL16(params->gain_cdbk[4 * best_gain_index + 3], 8), MAX32(1024, *cumul_gain)); #else *cumul_gain = 0.03125 * MAX32(1024, *cumul_gain) * params->gain_cdbk[4 * best_gain_index + 3]; #endif /*printf ("%f\n", cumul_gain);*/ /*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/ SPEEX_COPY(exc, best_exc, nsf); SPEEX_COPY(target, best_target, nsf); #ifdef FIXED_POINT /* Scale target back up if needed */ if (scaledown) { for (i = 0; i < nsf; i++) target[i] = SHL16(target[i], 1); } #endif return pitch; }
/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */ int pitch_search_3tap( spx_sig_t target[], /* Target vector */ spx_sig_t *sw, spx_coef_t ak[], /* LPCs for this subframe */ spx_coef_t awk1[], /* Weighted LPCs #1 for this subframe */ spx_coef_t awk2[], /* Weighted LPCs #2 for this subframe */ spx_sig_t exc[], /* Excitation */ const void *par, int start, /* Smallest pitch value allowed */ int end, /* Largest pitch value allowed */ spx_word16_t pitch_coef, /* Voicing (pitch) coefficient */ int p, /* Number of LPC coeffs */ int nsf, /* Number of samples in subframe */ SpeexBits *bits, char *stack, spx_sig_t *exc2, spx_word16_t *r, int complexity, int cdbk_offset, int plc_tuning ) { int i,j; int cdbk_index, pitch=0, best_gain_index=0; VARDECL(spx_sig_t *best_exc); VARDECL(spx_sig_t *new_target); VARDECL(spx_sig_t *best_target); int best_pitch=0; spx_word64_t err, best_err=-1; int N; const ltp_params *params; VARDECL(int *nbest); N=complexity; if (N>10) N=10; if (N<1) N=1; ALLOC(nbest, N, int); params = (const ltp_params*) par; if (end<start) { speex_bits_pack(bits, 0, params->pitch_bits); speex_bits_pack(bits, 0, params->gain_bits); for (i=0; i<nsf; i++) exc[i]=0; return start; } ALLOC(best_exc, nsf, spx_sig_t); ALLOC(new_target, nsf, spx_sig_t); ALLOC(best_target, nsf, spx_sig_t); if (N>end-start+1) N=end-start+1; open_loop_nbest_pitch(sw, start, end, nsf, nbest, NULL, N, stack); for (i=0; i<N; i++) { pitch=nbest[i]; for (j=0; j<nsf; j++) exc[j]=0; err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, par, pitch, p, nsf, bits, stack, exc2, r, new_target, &cdbk_index, cdbk_offset, plc_tuning); if (err<best_err || best_err<0) { for (j=0; j<nsf; j++) best_exc[j]=exc[j]; for (j=0; j<nsf; j++) best_target[j]=new_target[j]; best_err=err; best_pitch=pitch; best_gain_index=cdbk_index; } } /*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/ speex_bits_pack(bits, best_pitch-start, params->pitch_bits); speex_bits_pack(bits, best_gain_index, params->gain_bits); /*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/ for (i=0; i<nsf; i++) exc[i]=best_exc[i]; for (i=0; i<nsf; i++) target[i]=best_target[i]; return pitch; }