Mercurial > libavcodec.hg
diff qcelpdec.c @ 8240:d3d0d9cc0e50 libavcodec
Commit last ok'ed parts of QCELP decoder and enable it.
patch by Kenan Gillet, kenan.gillet gmail com
| author | vitor |
|---|---|
| date | Tue, 02 Dec 2008 16:48:05 +0000 |
| parents | 93ee77578391 |
| children | 75ae6859ac73 |
line wrap: on
line diff
--- a/qcelpdec.c Tue Dec 02 10:43:08 2008 +0000 +++ b/qcelpdec.c Tue Dec 02 16:48:05 2008 +0000 @@ -65,8 +65,8 @@ float last_codebook_gain; int prev_g1[2]; int prev_bitrate; - float prev_pitch_gain[4]; - uint8_t prev_pitch_lag[4]; + float pitch_gain[4]; + uint8_t pitch_lag[4]; uint16_t first16bits; } QCELPContext; @@ -75,7 +75,7 @@ * * TIA/EIA/IS-733 2.4.3.3.5 */ -void qcelp_lspf2lpc(const float *lspf, float *lpc); +void ff_qcelp_lspf2lpc(const float *lspf, float *lpc); static void weighted_vector_sumf(float *out, const float *in_a, const float *in_b, float weight_coeff_a, @@ -495,6 +495,58 @@ } /** + * Apply pitch synthesis filter and pitch prefilter to the scaled codebook vector. + * TIA/EIA/IS-733 2.4.5.2 + * + * @param q the context + * @param cdn_vector the scaled codebook vector + */ +static void apply_pitch_filters(QCELPContext *q, + float *cdn_vector) { + int i; + const float *v_synthesis_filtered, *v_pre_filtered; + + if (q->bitrate >= RATE_HALF || + (q->bitrate == I_F_Q && (q->prev_bitrate >= RATE_HALF))) { + + if (q->bitrate >= RATE_HALF) { + + // Compute gain & lag for the whole frame. + for (i = 0; i < 4; i++) { + q->pitch_gain[i] = q->frame.plag[i] ? (q->frame.pgain[i] + 1) * 0.25 : 0.0; + + q->pitch_lag[i] = q->frame.plag[i] + 16; + } + } else { + float max_pitch_gain = q->erasure_count < 3 ? 0.9 - 0.3 * (q->erasure_count - 1) + : 0.0; + for (i = 0; i < 4; i++) + q->pitch_gain[i] = FFMIN(q->pitch_gain[i], max_pitch_gain); + + memset(q->frame.pfrac, 0, sizeof(q->frame.pfrac)); + } + + // pitch synthesis filter + v_synthesis_filtered = do_pitchfilter(q->pitch_synthesis_filter_mem, cdn_vector, + q->pitch_gain, q->pitch_lag, q->frame.pfrac); + + // pitch prefilter update + for (i = 0; i < 4; i++) + q->pitch_gain[i] = 0.5 * FFMIN(q->pitch_gain[i], 1.0); + + v_pre_filtered = do_pitchfilter(q->pitch_pre_filter_mem, v_synthesis_filtered, + q->pitch_gain, q->pitch_lag, q->frame.pfrac); + + apply_gain_ctrl(cdn_vector, v_synthesis_filtered, v_pre_filtered); + } else { + memcpy(q->pitch_synthesis_filter_mem, cdn_vector + 17, 143 * sizeof(float)); + memcpy(q->pitch_pre_filter_mem, cdn_vector + 17, 143 * sizeof(float)); + memset(q->pitch_gain, 0, sizeof(q->pitch_gain)); + memset(q->pitch_lag, 0, sizeof(q->pitch_lag)); + } +} + +/** * Interpolates LSP frequencies and computes LPC coefficients * for a given bitrate & pitch subframe. * @@ -522,9 +574,9 @@ { weighted_vector_sumf(interpolated_lspf, curr_lspf, q->prev_lspf, weight, 1.0 - weight, 10); - qcelp_lspf2lpc(interpolated_lspf, lpc); + ff_qcelp_lspf2lpc(interpolated_lspf, lpc); }else if(q->bitrate >= RATE_QUARTER || (q->bitrate == I_F_Q && !subframe_num)) - qcelp_lspf2lpc(curr_lspf, lpc); + ff_qcelp_lspf2lpc(curr_lspf, lpc); } static int buf_size2bitrate(const int buf_size)
