[FFmpeg-devel] [PATCH] Common ACELP code & G.729 [2/7] - pitch lag decoding

Vladimir Voroshilov voroshil
Wed May 28 09:25:19 CEST 2008


2008/5/24 Michael Niedermayer <michaelni at gmx.at>:
> On Sat, May 24, 2008 at 12:11:16AM +0700, Vladimir Voroshilov wrote:

[...]

>> +int16_t ff_acelp_decode_gain_code(
>> +    int gain_corr_factor,
>> +    const int16_t* fc_v,
>> +    int mr_energy,
>> +    const int16_t* quant_energy,
>> +    const int16_t* ma_prediction_coeff,
>> +    int subframe_size,
>> +    int ma_pred_order)
>> +{
>> +    int i;
>> +    int energy;
>> +    int exp;
>> +
>> +    /* 3.9.1 of G.729, Equation 66 */
>> +    energy = sum_of_squares(fc_v, subframe_size, 0, 0);
>> +
>> +    /* 24660 = 10/log2(10) in (2.13) */
>> +    energy = -ff_log2(energy);
>> +    /* mr_energy = Em + 10log(N) + 10log(2^26) */
>> +    energy += mr_energy;
>> +
>> +    energy <<= 10; // (7.13) -> (7.23)
>> +    /* 3.9.1 of G.729, Equation 69 */
>> +    for(i=0; i<ma_pred_order; i++)
>> +        energy += quant_energy[i] * ma_prediction_coeff[i];
>> +
>> +    energy >>= 11;
>> +
>> +    /* The following code will calculate energy*2^14 instead of energy*2^exp
>> +       due to the recent change of the integer part of energy_int.
>> +       This is done to avoid overflow. Result fits into 16 bit. */
>> +    exp = (energy >> 15);             // integer part (exponent)
>> +    /* Only fraction part of (0.15) and rounding */
>> +    energy = ((ff_exp2(energy & 0x7fff) + 16) >> 5);
>> +
>> +    /* apply correction */
>> +    energy *= gain_corr_factor >> 1; // energy*2^14 in (3.12)
>> +
>> +    /* energy*2^14 in (3.12) -> energy*2^exp in (14.1) */
>> +    return bidir_sal(energy, exp - 25);
>
> if id ignore all scaling and overflows then this is just:
>
> energy= mr_energy;
> for(i=0; i<ma_pred_order; i++)
>    energy += quant_energy[i] * ma_prediction_coeff[i];
> return exp(energy) * gain_corr_factor / sum_of_squares(fc_v, subframe_size, 0, 0);



> This makes me quite unhappy as there is a huge difference in complexity.
> If we cant find a clean way with integers then i would suggest that this last
> line is done using floats.
>

I got  this floating-point (partially) implementation:

f_energy = 0;
 for(i=0; i<ma_pred_order; i++)
    f_energy += quant_energy[i] * ma_prediction_coeff[i];
f_energy = mean_energy + f_energy / (1<<23)
 return 2 * exp(M_LN10 * f_energy / 20) * gain_corr_factor /
sqrt(sum_of_squares(fc_v, subframe_size, 0, 0) / subframe_size);

Converting quant_energy and ma_prediction coeff to floats will avoid "/(1<<23)"
I'm not sure that this code is better.

-- 
Regards,
Vladimir Voroshilov mailto:voroshil at gmail.com
JID: voroshil at gmail.com, voroshil at jabber.ru
ICQ: 95587719




More information about the ffmpeg-devel mailing list