fixup
[lcr.git] / libgsmfr / src / lpc.c
1 /*
2  * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
3  * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
4  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
5  */
6
7 /* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/lpc.c,v 1.5 1994/12/30 23:14:54 jutta Exp $ */
8
9 #include <stdio.h>
10 #include <assert.h>
11
12 #include "private.h"
13
14 #include "gsm.h"
15 #include "proto.h"
16
17 #undef  P
18
19 /*
20  *  4.2.4 .. 4.2.7 LPC ANALYSIS SECTION
21  */
22
23 /* 4.2.4 */
24
25
26 static void Autocorrelation P2((s, L_ACF),
27         word     * s,           /* [0..159]     IN/OUT  */
28         longword * L_ACF)       /* [0..8]       OUT     */
29 /*
30  *  The goal is to compute the array L_ACF[k].  The signal s[i] must
31  *  be scaled in order to avoid an overflow situation.
32  */
33 {
34         register int    k, i;
35
36         word            temp, smax, scalauto;
37
38 #ifdef  USE_FLOAT_MUL
39         float           float_s[160];
40 #endif
41
42         /*  Dynamic scaling of the array  s[0..159]
43          */
44
45         /*  Search for the maximum.
46          */
47         smax = 0;
48         for (k = 0; k <= 159; k++) {
49                 temp = GSM_ABS( s[k] );
50                 if (temp > smax) smax = temp;
51         }
52
53         /*  Computation of the scaling factor.
54          */
55         if (smax == 0) scalauto = 0;
56         else {
57                 assert(smax > 0);
58                 scalauto = 4 - gsm_norm( (longword)smax << 16 );/* sub(4,..) */
59         }
60
61         /*  Scaling of the array s[0...159]
62          */
63
64         if (scalauto > 0) {
65
66 # ifdef USE_FLOAT_MUL
67 #   define SCALE(n)     \
68         case n: for (k = 0; k <= 159; k++) \
69                         float_s[k] = (float)    \
70                                 (s[k] = GSM_MULT_R(s[k], 16384 >> (n-1)));\
71                 break;
72 # else 
73 #   define SCALE(n)     \
74         case n: for (k = 0; k <= 159; k++) \
75                         s[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\
76                 break;
77 # endif /* USE_FLOAT_MUL */
78
79                 switch (scalauto) {
80                 SCALE(1)
81                 SCALE(2)
82                 SCALE(3)
83                 SCALE(4)
84                 }
85 # undef SCALE
86         }
87 # ifdef USE_FLOAT_MUL
88         else for (k = 0; k <= 159; k++) float_s[k] = (float) s[k];
89 # endif
90
91         /*  Compute the L_ACF[..].
92          */
93         {
94 # ifdef USE_FLOAT_MUL
95                 register float * sp = float_s;
96                 register float   sl = *sp;
97
98 #               define STEP(k)   L_ACF[k] += (longword)(sl * sp[ -(k) ]);
99 # else
100                 word  * sp = s;
101                 word    sl = *sp;
102
103 #               define STEP(k)   L_ACF[k] += ((longword)sl * sp[ -(k) ]);
104 # endif
105
106 #       define NEXTI     sl = *++sp
107
108
109         for (k = 9; k--; L_ACF[k] = 0) ;
110
111         STEP (0);
112         NEXTI;
113         STEP(0); STEP(1);
114         NEXTI;
115         STEP(0); STEP(1); STEP(2);
116         NEXTI;
117         STEP(0); STEP(1); STEP(2); STEP(3);
118         NEXTI;
119         STEP(0); STEP(1); STEP(2); STEP(3); STEP(4);
120         NEXTI;
121         STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5);
122         NEXTI;
123         STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6);
124         NEXTI;
125         STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7);
126
127         for (i = 8; i <= 159; i++) {
128
129                 NEXTI;
130
131                 STEP(0);
132                 STEP(1); STEP(2); STEP(3); STEP(4);
133                 STEP(5); STEP(6); STEP(7); STEP(8);
134         }
135
136         for (k = 9; k--; L_ACF[k] <<= 1) ; 
137
138         }
139         /*   Rescaling of the array s[0..159]
140          */
141         if (scalauto > 0) {
142                 assert(scalauto <= 4); 
143                 for (k = 160; k--; *s++ <<= scalauto) ;
144         }
145 }
146
147 #if defined(USE_FLOAT_MUL) && defined(FAST)
148
149 static void Fast_Autocorrelation P2((s, L_ACF),
150         word * s,               /* [0..159]     IN/OUT  */
151         longword * L_ACF)       /* [0..8]       OUT     */
152 {
153         register int    k, i;
154         float f_L_ACF[9];
155         float scale;
156
157         float          s_f[160];
158         register float *sf = s_f;
159
160         for (i = 0; i < 160; ++i) sf[i] = s[i];
161         for (k = 0; k <= 8; k++) {
162                 register float L_temp2 = 0;
163                 register float *sfl = sf - k;
164                 for (i = k; i < 160; ++i) L_temp2 += sf[i] * sfl[i];
165                 f_L_ACF[k] = L_temp2;
166         }
167         scale = MAX_LONGWORD / f_L_ACF[0];
168
169         for (k = 0; k <= 8; k++) {
170                 L_ACF[k] = f_L_ACF[k] * scale;
171         }
172 }
173 #endif  /* defined (USE_FLOAT_MUL) && defined (FAST) */
174
175 /* 4.2.5 */
176
177 static void Reflection_coefficients P2( (L_ACF, r),
178         longword        * L_ACF,                /* 0...8        IN      */
179         register word   * r                     /* 0...7        OUT     */
180 )
181 {
182         register int    i, m, n;
183         register word   temp;
184         register longword ltmp;
185         word            ACF[9]; /* 0..8 */
186         word            P[  9]; /* 0..8 */
187         word            K[  9]; /* 2..8 */
188
189         /*  Schur recursion with 16 bits arithmetic.
190          */
191
192         if (L_ACF[0] == 0) {
193                 for (i = 8; i--; *r++ = 0) ;
194                 return;
195         }
196
197         assert( L_ACF[0] != 0 );
198         temp = gsm_norm( L_ACF[0] );
199
200         assert(temp >= 0 && temp < 32);
201
202         /* ? overflow ? */
203         for (i = 0; i <= 8; i++) ACF[i] = SASR( L_ACF[i] << temp, 16 );
204
205         /*   Initialize array P[..] and K[..] for the recursion.
206          */
207
208         for (i = 1; i <= 7; i++) K[ i ] = ACF[ i ];
209         for (i = 0; i <= 8; i++) P[ i ] = ACF[ i ];
210
211         /*   Compute reflection coefficients
212          */
213         for (n = 1; n <= 8; n++, r++) {
214
215                 temp = P[1];
216                 temp = GSM_ABS(temp);
217                 if (P[0] < temp) {
218                         for (i = n; i <= 8; i++) *r++ = 0;
219                         return;
220                 }
221
222                 *r = gsm_div( temp, P[0] );
223
224                 assert(*r >= 0);
225                 if (P[1] > 0) *r = -*r;         /* r[n] = sub(0, r[n]) */
226                 assert (*r != MIN_WORD);
227                 if (n == 8) return; 
228
229                 /*  Schur recursion
230                  */
231                 temp = GSM_MULT_R( P[1], *r );
232                 P[0] = GSM_ADD( P[0], temp );
233
234                 for (m = 1; m <= 8 - n; m++) {
235                         temp     = GSM_MULT_R( K[ m   ],    *r );
236                         P[m]     = GSM_ADD(    P[ m+1 ],  temp );
237
238                         temp     = GSM_MULT_R( P[ m+1 ],    *r );
239                         K[m]     = GSM_ADD(    K[ m   ],  temp );
240                 }
241         }
242 }
243
244 /* 4.2.6 */
245
246 static void Transformation_to_Log_Area_Ratios P1((r),
247         register word   * r                     /* 0..7    IN/OUT */
248 )
249 /*
250  *  The following scaling for r[..] and LAR[..] has been used:
251  *
252  *  r[..]   = integer( real_r[..]*32768. ); -1 <= real_r < 1.
253  *  LAR[..] = integer( real_LAR[..] * 16384 );
254  *  with -1.625 <= real_LAR <= 1.625
255  */
256 {
257         register word   temp;
258         register int    i;
259
260
261         /* Computation of the LAR[0..7] from the r[0..7]
262          */
263         for (i = 1; i <= 8; i++, r++) {
264
265                 temp = *r;
266                 temp = GSM_ABS(temp);
267                 assert(temp >= 0);
268
269                 if (temp < 22118) {
270                         temp >>= 1;
271                 } else if (temp < 31130) {
272                         assert( temp >= 11059 );
273                         temp -= 11059;
274                 } else {
275                         assert( temp >= 26112 );
276                         temp -= 26112;
277                         temp <<= 2;
278                 }
279
280                 *r = *r < 0 ? -temp : temp;
281                 assert( *r != MIN_WORD );
282         }
283 }
284
285 /* 4.2.7 */
286
287 static void Quantization_and_coding P1((LAR),
288         register word * LAR     /* [0..7]       IN/OUT  */
289 )
290 {
291         register word   temp;
292         longword        ltmp;
293
294
295         /*  This procedure needs four tables; the following equations
296          *  give the optimum scaling for the constants:
297          *  
298          *  A[0..7] = integer( real_A[0..7] * 1024 )
299          *  B[0..7] = integer( real_B[0..7] *  512 )
300          *  MAC[0..7] = maximum of the LARc[0..7]
301          *  MIC[0..7] = minimum of the LARc[0..7]
302          */
303
304 #       undef STEP
305 #       define  STEP( A, B, MAC, MIC )          \
306                 temp = GSM_MULT( A,   *LAR );   \
307                 temp = GSM_ADD(  temp,   B );   \
308                 temp = GSM_ADD(  temp, 256 );   \
309                 temp = SASR(     temp,   9 );   \
310                 *LAR  =  temp>MAC ? MAC - MIC : (temp<MIC ? 0 : temp - MIC); \
311                 LAR++;
312
313         STEP(  20480,     0,  31, -32 );
314         STEP(  20480,     0,  31, -32 );
315         STEP(  20480,  2048,  15, -16 );
316         STEP(  20480, -2560,  15, -16 );
317
318         STEP(  13964,    94,   7,  -8 );
319         STEP(  15360, -1792,   7,  -8 );
320         STEP(   8534,  -341,   3,  -4 );
321         STEP(   9036, -1144,   3,  -4 );
322
323 #       undef   STEP
324 }
325
326 void Gsm_LPC_Analysis P3((S, s,LARc),
327         struct gsm_state *S,
328         word             * s,           /* 0..159 signals       IN/OUT  */
329         word             * LARc)        /* 0..7   LARc's        OUT     */
330 {
331         longword        L_ACF[9];
332
333 #if defined(USE_FLOAT_MUL) && defined(FAST)
334         if (S->fast) Fast_Autocorrelation (s,     L_ACF );
335         else
336 #endif
337         Autocorrelation                   (s,     L_ACF );
338         Reflection_coefficients           (L_ACF, LARc  );
339         Transformation_to_Log_Area_Ratios (LARc);
340         Quantization_and_coding           (LARc);
341 }