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

Michael Niedermayer michaelni
Fri May 9 21:49:23 CEST 2008


On Fri, May 09, 2008 at 01:31:02PM +0700, Vladimir Voroshilov wrote:
> Michael Niedermayer wrote: 
> > On Fri, May 02, 2008 at 06:36:34PM +0700, Vladimir Voroshilov wrote:
> 
> [...]
> 
> > > +        int subframeno,
> > > +        int pitch_lag_min)
> > > +{
> > > +    // (4.1.3 of G.729 and 5.6.1 of AMR)
> > > +    if (!subframeno)
> > > +        return decode_lag3_1st_8_bits(ac_index);
> > > +    else
> > > +        return 3*pitch_lag_min + ac_index - 1;
> > > +}
> > 
> > It seems as if it would be simpler to do the if (!subframeno) check outside
> > after all its always doing the same, this would also avoid having to pass
> > subframeno as argument.
> 
> See patch.

[...]
> +int ff_acelp_decode_lag3_2nd_8_4_bits(
> +        int ac_index,
> +        int pitch_lag_min)
> +{
> +    ac_index &= 0xf;
> +
> +    if(ac_index < 4)
> +        return 3*(ac_index + pitch_lag_min) + 1;
> +    else if(ac_index < 12)
> +        return 3*pitch_lag_min + ac_index + 7;
> +    else
> +        return 3*(ac_index + pitch_lag_min) - 17;
> +}

if ac_index is 4 bits as the doxy says, then the & 0xf should not be needed


[...]
> +void ff_acelp_update_past_gain_erasure(int16_t *quant_energy, int ma_pred_order)
> +{
> +    int avg_gain=quant_energy[ma_pred_order-1]; // (5.10)
> +    int i;
> +
> +    /* 4.4.3. Equation 95 of G.729 */
> +    for(i=ma_pred_order-1; i>0; i--)
> +    {
> +        avg_gain       += quant_energy[i-1];
> +        quant_energy[i] = quant_energy[i-1];
> +    }
> +av_log(NULL, AV_LOG_ERROR, "%d %d %d\n", ma_pred_order, (avg_gain>>2), (avg_gain/ma_pred_order));

> +    quant_energy[0] = FFMAX((avg_gain / ma_pred_order) - 4096, -14336); // -14 in (5.10)
> +//    quant_energy[0] = FFMAX((avg_gain >> 2) - 4096, -14336); // -14 in (5.10)

why the commented out line?

and
quant_energy[0] = FFMAX(avg_gain / ma_pred_order, -10240) - 4096;
looks nicer to me


> +}
> +
> +void ff_acelp_update_past_gain(int16_t* quant_energy, int gain_corr_factor, int ma_pred_order)
> +{
> +    int i;
> +

> +    // shift prediction energy vector
> +    for(i=ma_pred_order-1; i>0; i--)
> +        quant_energy[i] = quant_energy[i-1];

duplicate of above


> +
> +    /* 3.9.1, Equation 72 */
> +    /*
> +      quant_energy[0] = 20*log10(gain_corr_factor) in (3.12)
> +      24660 = 10/log2(10) in (2.13)
> +    */
> +    quant_energy[0] = (24660 * av_clip_int16((ff_log2(gain_corr_factor) >> 2) - (13 << 13))) >> 15;
> +}

> +
> +int16_t ff_acelp_decode_gain_code(
> +    int gain_corr_factor,
> +    const int16_t* fc_v,
> +    int mean_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, Equation 66 of G.729 */
> +    energy = sum_of_squares(fc_v, subframe_size, 0, 0);
> +
> +    /*
> +      mean_energy is in (6.13)
> +      energy=mean_energy-E
> +      E is calculated as following (3.9.1 Equation 66 of G.729)
> +
> +      E = 10 * log10(energy / (2^26 * subframe_size))
> +      = 10 * log2(energy / (2^26 * subframe_size)) / log2(10)
> +      = 10*log2(energy/2^26)/log2(10) - 10*log2(subframe_size)/log2(10)
> +      = [10/log2(10)] * log2(energy/2^26) - [10/log2(10)] * log2(subframe_size)
> +      = 24660 * log2(energy) - 24660 * log2(subframe_size) - 24660 * 26
> +
> +      24660 = 10/log2(10) in (2.13)
> +    */
> +    energy =  MULL(ff_log2(energy),       -24660);

> +    energy += MULL(ff_log2(subframe_size), 24660);
> +    energy += 0x9c888; // 24660 * 26
> +    energy += mean_energy;
> +
> +#ifdef G729_BITEXACT
> +    /*
> +       Reference code uses a constant instead of the two previous lines.
> +       That value (due to 2^6 rounding) differs by 2 from code above.
> +       Subtracting 2 from energy makes the result be bit-equal with
> +       the reference code.
> +    */
> +    energy -= 2;
> +#endif

wouldnt it be easier to just pass the sum of these as argument?


> +
> +    energy <<= 10; // (7.13) -> (7.23)
> +    /* 3.9.1, Equation 69 of G.729*/
> +    for(i=0; i<ma_pred_order; i++)
> +        energy += quant_energy[i] * ma_prediction_coeff[i];
> +
> +    /* 3.9.1, Equation 71 of G.729*/
> +    /*
> +      energy = 10^(energy / 20) = 2^(3.3219 * energy / 20) = 2^ (0.166 * energy)
> +      5439 = 0.166 in (0.15)
> +    */
> +    energy = (5439 * (energy >> 15)) >> 8; // (0.15) = (0.15) * (7.23)
> +
> +    /*
> +      The following code will calculate energy*2^14 instead of energy*2^exp
> +      due to the recent change of the ineger 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) & 0x7fff;

is the second & 0x7fff needed?


> +
> +    // 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)
> +    if(exp > 25)
> +        energy <<= exp - 25;
> +    else
> +        energy >>= 25 - exp;

seperate function


[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Breaking DRM is a little like attempting to break through a door even
though the window is wide open and the only thing in the house is a bunch
of things you dont want and which you would get tomorrow for free anyway
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20080509/26e38ce4/attachment.pgp>



More information about the ffmpeg-devel mailing list