# [FFmpeg-devel] [PATCH] Common fixed-point ACELP routines (1/3) - math

Michael Niedermayer michaelni
Thu Apr 24 20:03:32 CEST 2008

```On Thu, Apr 24, 2008 at 11:10:24PM +0700, Vladimir Voroshilov wrote:
[...]
> +int ff_exp2(uint16_t power)
> +{
> +    unsigned int result= exp2a[power>>10] + 0x10000;
> +
> +    assert(arg <= 0x7fff);
> +
> +    result= (result<<4) + ((result*exp2b[(power>>5)&31])>>16);
> +    result=  result     + ((result*exp2c[ power    &31])>>18);
> +    return result;
> +}

following is a tiny bit more accurate and doesnt need the 3rd table:

static const uint16_t exp2a[]={
0,  1435,  2901,  4400,  5931,  7496,  9096, 10730,
12400, 14106, 15850, 17632, 19454, 21315, 23216, 25160,
27146, 29175, 31249, 33368, 35534, 37747, 40009, 42320,
44682, 47095, 49562, 52082, 54657, 57289, 59979, 62727,

};
static const uint16_t exp2b[]={
3,   712,  1424,  2134,  2845,  3557,  4270,  4982,
5696,  6409,  7124,  7839,  8554,  9270,  9986, 10704,
11421, 12138, 12857, 13576, 14295, 15014, 15734, 16455,
17176, 17898, 18620, 19343, 20066, 20790, 21514, 22238,

};

unsigned int result= exp2a[power>>10] + 0x10000;

result= (result<<3) + ((result*exp2b[(power>>5)&31])>>17);
return result + ((result*(power&31)*89)>>22);

Note, yes the output is scaled different again

[...]
> +/**
> + * \brief multiplies 32-bit integer by another 16-bit and divides result by 2^15
> + * \param var_q24 32-bit integer
> + * \param var_15 16-bit integer
> + *
> + * \return result of (var_q24 * var_q15 >> 15) with clipping to [INT_MIN; INT_MAX] range
> + */
> +static inline int mul_32_16(int var_q24, int16_t var_q15)
> +{
> +    return (((int64_t)var_q24 * (int64_t)var_q15) >> 15);
> +}

now this looks like it belongs to libavcodec/mathops.h

> +
> +/**
> + * \brief Calculates sum of array elements multiplications
> + * \param speech array with input data
> + * \param cycles number elements to proceed
> + * \param offset offset for calculation sum of s[i]*s[i+offset]
> + * \param shift right shift by this value will be done before multiplication
> + *
> + * \return sum of multiplications
> + *
> + * \note array must be at least length+offset long!
> + */
> +static int sum_of_squares(const int16_t* speech, int cycles, int offset, int shift)
> +{
> +    const int16_t* speech_end;
> +    int sum = 0;
> +
> +    for(speech_end=speech+cycles; speech<speech_end; speech++)
> +       sum += (speech[0] * speech[offset]) >> (shift << 1);

IMHO the shift << 1 should be done outside this function

[...]
--

The misfortune of the wise is better than the prosperity of the fool.
-- Epicurus
-------------- 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/20080424/3c714b47/attachment.pgp>

```