[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
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
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>
More information about the ffmpeg-devel
mailing list