[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