/** * Decode a set of 3 split-matrix quantized lsf indexes into an lsp vector. * * @param p pointer to the AMRContext */ static void lsf2lsp_3(AMRContext *p) { const uint16_t *lsf_param = p->frame.lsf; int16_t lsf_r[LP_FILTER_ORDER]; // residual LSF vector float lsf_q[LP_FILTER_ORDER]; // quantified LSF vector const int16_t *lsf_quantizer; int i, j; lsf_quantizer = (p->cur_frame_mode == MODE_7k95 ? lsf_3_1_MODE_7k95 : lsf_3_1)[lsf_param[0]]; memcpy(lsf_r, lsf_quantizer, 3 * sizeof(*lsf_r)); lsf_quantizer = lsf_3_2[lsf_param[1] << (p->cur_frame_mode <= MODE_5k15)]; memcpy(lsf_r + 3, lsf_quantizer, 3 * sizeof(*lsf_r)); lsf_quantizer = (p->cur_frame_mode <= MODE_5k15 ? lsf_3_3_MODE_5k15 : lsf_3_3)[lsf_param[2]]; memcpy(lsf_r + 6, lsf_quantizer, 4 * sizeof(*lsf_r)); // calculate mean-removed LSF vector and add mean for (i = 0; i < LP_FILTER_ORDER; i++) lsf_q[i] = (lsf_r[i] + p->prev_lsf_r[i] * pred_fac[i]) * (LSF_R_FAC / 8000.0) + lsf_3_mean[i] * (1.0 / 8000.0); ff_set_min_dist_lsf(lsf_q, MIN_LSF_SPACING, LP_FILTER_ORDER); // store data for computing the next frame's LSFs interpolate_lsf(p->lsf_q, lsf_q); memcpy(p->prev_lsf_r, lsf_r, LP_FILTER_ORDER * sizeof(*lsf_r)); ff_acelp_lsf2lspd(p->lsp[3], lsf_q, LP_FILTER_ORDER); // interpolate LSP vectors at subframes 1, 2 and 3 for (i = 1; i <= 3; i++) for(j = 0; j < LP_FILTER_ORDER; j++) p->lsp[i-1][j] = p->prev_lsp_sub4[j] + (p->lsp[3][j] - p->prev_lsp_sub4[j]) * 0.25 * i; }
/** * Decode a set of 5 split-matrix quantized lsf indexes into an lsp vector. * * @param p the context * @param lsp output LSP vector * @param lsf_no_r LSF vector without the residual vector added * @param lsf_quantizer pointers to LSF dictionary tables * @param quantizer_offset offset in tables * @param sign for the 3 dictionary table * @param update store data for computing the next frame's LSFs */ static void lsf2lsp_for_mode12k2(AMRContext *p, double lsp[LP_FILTER_ORDER], const float lsf_no_r[LP_FILTER_ORDER], const int16_t *lsf_quantizer[5], const int quantizer_offset, const int sign, const int update) { int16_t lsf_r[LP_FILTER_ORDER]; // residual LSF vector float lsf_q[LP_FILTER_ORDER]; // quantified LSF vector int i; for (i = 0; i < LP_FILTER_ORDER >> 1; i++) memcpy(&lsf_r[i << 1], &lsf_quantizer[i][quantizer_offset], 2 * sizeof(*lsf_r)); if (sign) { lsf_r[4] *= -1; lsf_r[5] *= -1; } if (update) memcpy(p->prev_lsf_r, lsf_r, LP_FILTER_ORDER * sizeof(*lsf_r)); for (i = 0; i < LP_FILTER_ORDER; i++) lsf_q[i] = lsf_r[i] * (LSF_R_FAC / 8000.0) + lsf_no_r[i] * (1.0 / 8000.0); ff_set_min_dist_lsf(lsf_q, MIN_LSF_SPACING, LP_FILTER_ORDER); if (update) interpolate_lsf(p->lsf_q, lsf_q); ff_acelp_lsf2lspd(lsp, lsf_q, LP_FILTER_ORDER); }
static void lsf_decode_fp(float *lsfnew, float *lsf_history, const SiprParameters *parm) { int i; float lsf_tmp[LP_FILTER_ORDER]; dequant(lsf_tmp, parm->vq_indexes, lsf_codebooks); for (i = 0; i < LP_FILTER_ORDER; i++) lsfnew[i] = lsf_history[i] * 0.33 + lsf_tmp[i] + mean_lsf[i]; ff_sort_nearly_sorted_floats(lsfnew, LP_FILTER_ORDER - 1); /* Note that a minimum distance is not enforced between the last value and the previous one, contrary to what is done in ff_acelp_reorder_lsf() */ ff_set_min_dist_lsf(lsfnew, LSFQ_DIFF_MIN, LP_FILTER_ORDER - 1); lsfnew[9] = FFMIN(lsfnew[LP_FILTER_ORDER - 1], 1.3 * M_PI); memcpy(lsf_history, lsf_tmp, LP_FILTER_ORDER * sizeof(*lsf_history)); for (i = 0; i < LP_FILTER_ORDER - 1; i++) lsfnew[i] = cos(lsfnew[i]); lsfnew[LP_FILTER_ORDER - 1] *= 6.153848 / M_PI; }
void ff_sipr_decode_frame_16k(SiprContext *ctx, SiprParameters *params, float *out_data) { int frame_size = SUBFRAME_COUNT_16k * L_SUBFR_16k; float *synth = ctx->synth_buf + LP_FILTER_ORDER_16k; float lsf_new[LP_FILTER_ORDER_16k]; double lsp_new[LP_FILTER_ORDER_16k]; float Az[2][LP_FILTER_ORDER_16k]; float fixed_vector[L_SUBFR_16k]; float pitch_fac, gain_code; int i; int pitch_delay_3x; float *excitation = ctx->excitation + 292; lsf_decode_fp_16k(ctx->lsf_history, lsf_new, params->vq_indexes, params->ma_pred_switch); ff_set_min_dist_lsf(lsf_new, LSFQ_DIFF_MIN / 2, LP_FILTER_ORDER_16k); lsf2lsp(lsf_new, lsp_new); acelp_lp_decodef(Az[0], Az[1], lsp_new, ctx->lsp_history_16k); memcpy(ctx->lsp_history_16k, lsp_new, LP_FILTER_ORDER_16k * sizeof(double)); memcpy(synth - LP_FILTER_ORDER_16k, ctx->synth, LP_FILTER_ORDER_16k * sizeof(*synth)); for (i = 0; i < SUBFRAME_COUNT_16k; i++) { int i_subfr = i * L_SUBFR_16k; AMRFixed f; float gain_corr_factor; int pitch_delay_int; int pitch_delay_frac; if (!i) { pitch_delay_3x = dec_delay3_1st(params->pitch_delay[i]); } else pitch_delay_3x = dec_delay3_2nd(params->pitch_delay[i], PITCH_MIN, PITCH_MAX, ctx->pitch_lag_prev); pitch_fac = gain_pitch_cb_16k[params->gp_index[i]]; f.pitch_fac = FFMIN(pitch_fac, 1.0); f.pitch_lag = DIVIDE_BY_3(pitch_delay_3x+1); ctx->pitch_lag_prev = f.pitch_lag; pitch_delay_int = DIVIDE_BY_3(pitch_delay_3x + 2); pitch_delay_frac = pitch_delay_3x + 2 - 3*pitch_delay_int; ff_acelp_interpolatef(&excitation[i_subfr], &excitation[i_subfr] - pitch_delay_int + 1, sinc_win, 3, pitch_delay_frac + 1, LP_FILTER_ORDER, L_SUBFR_16k); memset(fixed_vector, 0, sizeof(fixed_vector)); ff_decode_10_pulses_35bits(params->fc_indexes[i], &f, ff_fc_4pulses_8bits_tracks_13, 5, 4); ff_set_fixed_vector(fixed_vector, &f, 1.0, L_SUBFR_16k); gain_corr_factor = gain_cb_16k[params->gc_index[i]]; gain_code = gain_corr_factor * acelp_decode_gain_codef(sqrt(L_SUBFR_16k), fixed_vector, 19.0 - 15.0/(0.05*M_LN10/M_LN2), pred_16k, ctx->energy_history, L_SUBFR_16k, 2); ctx->energy_history[1] = ctx->energy_history[0]; ctx->energy_history[0] = 20.0 * log10f(gain_corr_factor); ff_weighted_vector_sumf(&excitation[i_subfr], &excitation[i_subfr], fixed_vector, pitch_fac, gain_code, L_SUBFR_16k); ff_celp_lp_synthesis_filterf(synth + i_subfr, Az[i], &excitation[i_subfr], L_SUBFR_16k, LP_FILTER_ORDER_16k); } memcpy(ctx->synth, synth + frame_size - LP_FILTER_ORDER_16k, LP_FILTER_ORDER_16k * sizeof(*synth)); memmove(ctx->excitation, ctx->excitation + 2 * L_SUBFR_16k, (L_INTERPOL+PITCH_MAX) * sizeof(float)); postfilter(out_data, synth, ctx->iir_mem, ctx->filt_mem, ctx->mem_preemph); memcpy(ctx->iir_mem, Az[1], LP_FILTER_ORDER_16k * sizeof(float)); }