1e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*
2e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Copyright 2003-2010, VisualOn, Inc.
3e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
4e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Licensed under the Apache License, Version 2.0 (the "License");
5e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** you may not use this file except in compliance with the License.
6e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** You may obtain a copy of the License at
7e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
8e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **     http://www.apache.org/licenses/LICENSE-2.0
9e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard **
10e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Unless required by applicable law or agreed to in writing, software
11e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** distributed under the License is distributed on an "AS IS" BASIS,
12e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** See the License for the specific language governing permissions and
14e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** limitations under the License.
15e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard */
16e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
17e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*___________________________________________________________________________
18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|                                                                           |
19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|  This file contains mathematic operations in fixed point.                 |
20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|                                                                           |
21e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|  Isqrt()              : inverse square root (16 bits precision).          |
22e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|  Pow2()               : 2^x  (16 bits precision).                         |
23e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|  Log2()               : log2 (16 bits precision).                         |
24e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|  Dot_product()        : scalar product of <x[],y[]>                       |
25e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|                                                                           |
26e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|  These operations are not standard double precision operations.           |
27e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|  They are used where low complexity is important and the full 32 bits     |
28e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|  precision is not necessary. For example, the function Div_32() has a     |
29e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|  24 bits precision which is enough for our purposes.                      |
30e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|                                                                           |
31e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|  In this file, the values use theses representations:                     |
32e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|                                                                           |
33e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|  Word32 L_32     : standard signed 32 bits format                         |
34e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|  Word16 hi, lo   : L_32 = hi<<16 + lo<<1  (DPF - Double Precision Format) |
35e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|  Word32 frac, Word16 exp : L_32 = frac << exp-31  (normalised format)     |
36e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|  Word16 int, frac        : L_32 = int.frac        (fractional format)     |
37e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|___________________________________________________________________________|
38e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*/
39e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "typedef.h"
40e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "basic_op.h"
41e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "math_op.h"
42e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
43e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*___________________________________________________________________________
44e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|                                                                           |
45e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   Function Name : Isqrt                                                   |
46e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|                                                                           |
47e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|       Compute 1/sqrt(L_x).                                                |
48e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|       if L_x is negative or zero, result is 1 (7fffffff).                 |
49e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|---------------------------------------------------------------------------|
50e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|  Algorithm:                                                               |
51e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|                                                                           |
52e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   1- Normalization of L_x.                                                |
53e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   2- call Isqrt_n(L_x, exponant)                                          |
54e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   3- L_y = L_x << exponant                                                |
55e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|___________________________________________________________________________|
56e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*/
57e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardWord32 Isqrt(                              /* (o) Q31 : output value (range: 0<=val<1)         */
58e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word32 L_x                            /* (i) Q0  : input value  (range: 0<=val<=7fffffff) */
59e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	    )
60e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
61e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 exp;
62e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 L_y;
63e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	exp = norm_l(L_x);
64e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	L_x = (L_x << exp);                 /* L_x is normalized */
65e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	exp = (31 - exp);
66e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Isqrt_n(&L_x, &exp);
67e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	L_y = (L_x << exp);                 /* denormalization   */
68e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return (L_y);
69e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
70e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
71e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*___________________________________________________________________________
72e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|                                                                           |
73e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   Function Name : Isqrt_n                                                 |
74e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|                                                                           |
75e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|       Compute 1/sqrt(value).                                              |
76e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|       if value is negative or zero, result is 1 (frac=7fffffff, exp=0).   |
77e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|---------------------------------------------------------------------------|
78e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|  Algorithm:                                                               |
79e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|                                                                           |
80e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   The function 1/sqrt(value) is approximated by a table and linear        |
81e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   interpolation.                                                          |
82e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|                                                                           |
83e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   1- If exponant is odd then shift fraction right once.                   |
84e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   2- exponant = -((exponant-1)>>1)                                        |
85e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   3- i = bit25-b30 of fraction, 16 <= i <= 63 ->because of normalization. |
86e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   4- a = bit10-b24                                                        |
87e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   5- i -=16                                                               |
88e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   6- fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2            |
89e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|___________________________________________________________________________|
90e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*/
91e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 table_isqrt[49] =
92e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
93e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	32767, 31790, 30894, 30070, 29309, 28602, 27945, 27330, 26755, 26214,
94e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	25705, 25225, 24770, 24339, 23930, 23541, 23170, 22817, 22479, 22155,
95e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	21845, 21548, 21263, 20988, 20724, 20470, 20225, 19988, 19760, 19539,
96e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	19326, 19119, 18919, 18725, 18536, 18354, 18176, 18004, 17837, 17674,
97e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	17515, 17361, 17211, 17064, 16921, 16782, 16646, 16514, 16384
98e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard};
99e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
100e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid Isqrt_n(
101e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word32 * frac,                        /* (i/o) Q31: normalized value (1.0 < frac <= 0.5) */
102e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 * exp                          /* (i/o)    : exponent (value = frac x 2^exponent) */
103e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	    )
104e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
105e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 i, a, tmp;
106e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
107e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if (*frac <= (Word32) 0)
108e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
109b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*exp = 0;
110b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard		*frac = 0x7fffffffL;
111e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		return;
112e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
113e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
114e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	if((*exp & 1) == 1)                       /*If exponant odd -> shift right */
115e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		*frac = (*frac) >> 1;
116e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
117b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	*exp = negate((*exp - 1) >> 1);
118e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
119b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	*frac = (*frac >> 9);
120e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	i = extract_h(*frac);                  /* Extract b25-b31 */
121b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	*frac = (*frac >> 1);
122e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	a = (Word16)(*frac);                  /* Extract b10-b24 */
123b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	a = (Word16) (a & (Word16) 0x7fff);
124e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	i -= 16;
125e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	*frac = L_deposit_h(table_isqrt[i]);   /* table[i] << 16         */
126e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	tmp = vo_sub(table_isqrt[i], table_isqrt[i + 1]);      /* table[i] - table[i+1]) */
127e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	*frac = vo_L_msu(*frac, tmp, a);          /* frac -=  tmp*a*2       */
128e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
129e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return;
130e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
131e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
132e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*___________________________________________________________________________
133e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|                                                                           |
134e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   Function Name : Pow2()                                                  |
135e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|                                                                           |
136e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|     L_x = pow(2.0, exponant.fraction)         (exponant = interger part)  |
137e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|         = pow(2.0, 0.fraction) << exponant                                |
138e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|---------------------------------------------------------------------------|
139e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|  Algorithm:                                                               |
140e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|                                                                           |
141e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   The function Pow2(L_x) is approximated by a table and linear            |
142e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   interpolation.                                                          |
143e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|                                                                           |
144e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   1- i = bit10-b15 of fraction,   0 <= i <= 31                            |
145e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   2- a = bit0-b9   of fraction                                            |
146e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   3- L_x = table[i]<<16 - (table[i] - table[i+1]) * a * 2                 |
147e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   4- L_x = L_x >> (30-exponant)     (with rounding)                       |
148e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|___________________________________________________________________________|
149e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*/
150e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 table_pow2[33] =
151e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
152e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	16384, 16743, 17109, 17484, 17867, 18258, 18658, 19066, 19484, 19911,
153e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	20347, 20792, 21247, 21713, 22188, 22674, 23170, 23678, 24196, 24726,
154e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	25268, 25821, 26386, 26964, 27554, 28158, 28774, 29405, 30048, 30706,
155e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	31379, 32066, 32767
156e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard};
157e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
158e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardWord32 Pow2(                               /* (o) Q0  : result       (range: 0<=val<=0x7fffffff) */
159e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 exponant,                      /* (i) Q0  : Integer part.      (range: 0<=val<=30)   */
160e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 fraction                       /* (i) Q15 : Fractionnal part.  (range: 0.0<=val<1.0) */
161e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	   )
162e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
163e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 exp, i, a, tmp;
164e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 L_x;
165e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
166e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	L_x = vo_L_mult(fraction, 32);            /* L_x = fraction<<6           */
167e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	i = extract_h(L_x);                    /* Extract b10-b16 of fraction */
168e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	L_x =L_x >> 1;
169e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	a = (Word16)(L_x);                    /* Extract b0-b9   of fraction */
170b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard	a = (Word16) (a & (Word16) 0x7fff);
171e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
172e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	L_x = L_deposit_h(table_pow2[i]);      /* table[i] << 16        */
173e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	tmp = vo_sub(table_pow2[i], table_pow2[i + 1]);        /* table[i] - table[i+1] */
174e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	L_x -= (tmp * a)<<1;              /* L_x -= tmp*a*2        */
175e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
176e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	exp = vo_sub(30, exponant);
177e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	L_x = vo_L_shr_r(L_x, exp);
178e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
179e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return (L_x);
180e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
181e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
182e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/*___________________________________________________________________________
183e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|                                                                           |
184e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|   Function Name : Dot_product12()                                         |
185e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|                                                                           |
186e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|       Compute scalar product of <x[],y[]> using accumulator.              |
187e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|                                                                           |
188e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|       The result is normalized (in Q31) with exponent (0..30).            |
189e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|---------------------------------------------------------------------------|
190e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|  Algorithm:                                                               |
191e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|                                                                           |
192e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|       dot_product = sum(x[i]*y[i])     i=0..N-1                           |
193e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard|___________________________________________________________________________|
194e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard*/
195e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
196e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardWord32 Dot_product12(                      /* (o) Q31: normalized result (1 < val <= -1) */
197e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 x[],                           /* (i) 12bits: x vector                       */
198e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 y[],                           /* (i) 12bits: y vector                       */
199e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 lg,                            /* (i)    : vector length                     */
200e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		Word16 * exp                          /* (o)    : exponent of result (0..+30)       */
201e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		)
202e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{
203e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word16 sft;
204e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	Word32 i, L_sum;
205e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	L_sum = 0;
206e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	for (i = 0; i < lg; i++)
207e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	{
208e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard		L_sum += x[i] * y[i];
209e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	}
210e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	L_sum = (L_sum << 1) + 1;
211e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	/* Normalize acc in Q31 */
212e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	sft = norm_l(L_sum);
213e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	L_sum = L_sum << sft;
214e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	*exp = 30 - sft;            /* exponent = 0..30 */
215e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard	return (L_sum);
216e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
217e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard}
218e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
219e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard
220