1 /*
2  * rpe.c
3  *
4  * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
5  * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
6  * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
7  */
8 
9 
10 #include <stdio.h>
11 #include <assert.h>
12 
13 #include "private.h"
14 
15 #include "gsm.h"
16 #include "proto.h"
17 
18 /*  4.2.13 .. 4.2.17  RPE ENCODING SECTION
19  */
20 
21 /* 4.2.13 */
22 
23 static void Weighting_filter P2((e, x),
24 	register word	* e,		/* signal [-5..0.39.44]	IN  */
25 	word		* x		/* signal [0..39]	OUT */
26 )
27 /*
28  *  The coefficients of the weighting filter are stored in a table
29  *  (see table 4.4).  The following scaling is used:
30  *
31  *	H[0..10] = integer( real_H[ 0..10] * 8192 );
32  */
33 {
34 	/* word			wt[ 50 ]; */
35 
36 	register longword	L_result;
37 	register int		k /* , i */ ;
38 
39 	/*  Initialization of a temporary working array wt[0...49]
40 	 */
41 
42 	/* for (k =  0; k <=  4; k++) wt[k] = 0;
43 	 * for (k =  5; k <= 44; k++) wt[k] = *e++;
44 	 * for (k = 45; k <= 49; k++) wt[k] = 0;
45 	 *
46 	 *  (e[-5..-1] and e[40..44] are allocated by the caller,
47 	 *  are initially zero and are not written anywhere.)
48 	 */
49 	e -= 5;
50 
51 	/*  Compute the signal x[0..39]
52 	 */
53 	for (k = 0; k <= 39; k++) {
54 
55 		L_result = 8192 >> 1;
56 
57 		/* for (i = 0; i <= 10; i++) {
58 		 *	L_temp   = GSM_L_MULT( wt[k+i], gsm_H[i] );
59 		 *	L_result = GSM_L_ADD( L_result, L_temp );
60 		 * }
61 		 */
62 
63 #undef	STEP
64 #define	STEP( i, H )	(e[ k + i ] * (longword)H)
65 
66 		/*  Every one of these multiplications is done twice --
67 		 *  but I don't see an elegant way to optimize this.
68 		 *  Do you?
69 		 */
70 
71 #ifdef	STUPID_COMPILER
72 		L_result += STEP(	0, 	-134 ) ;
73 		L_result += STEP(	1, 	-374 )  ;
74 	               /* + STEP(	2, 	0    )  */
75 		L_result += STEP(	3, 	2054 ) ;
76 		L_result += STEP(	4, 	5741 ) ;
77 		L_result += STEP(	5, 	8192 ) ;
78 		L_result += STEP(	6, 	5741 ) ;
79 		L_result += STEP(	7, 	2054 ) ;
80 	 	       /* + STEP(	8, 	0    )  */
81 		L_result += STEP(	9, 	-374 ) ;
82 		L_result += STEP(	10, 	-134 ) ;
83 #else
84 		L_result +=
85 		  STEP(	0, 	-134 )
86 		+ STEP(	1, 	-374 )
87 	     /* + STEP(	2, 	0    )  */
88 		+ STEP(	3, 	2054 )
89 		+ STEP(	4, 	5741 )
90 		+ STEP(	5, 	8192 )
91 		+ STEP(	6, 	5741 )
92 		+ STEP(	7, 	2054 )
93 	     /* + STEP(	8, 	0    )  */
94 		+ STEP(	9, 	-374 )
95 		+ STEP(10, 	-134 )
96 		;
97 #endif
98 
99 		/* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *)
100 		 * L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *)
101 		 *
102 		 * x[k] = SASR( L_result, 16 );
103 		 */
104 
105 		/* 2 adds vs. >>16 => 14, minus one shift to compensate for
106 		 * those we lost when replacing L_MULT by '*'.
107 		 */
108 
109 		L_result = SASR( L_result, 13 );
110 		x[k] =  (word) ((  L_result < MIN_WORD ? MIN_WORD
111 			: (L_result > MAX_WORD ? MAX_WORD : L_result )));
112 	}
113 }
114 
115 /* 4.2.14 */
116 
117 static void RPE_grid_selection P3((x,xM,Mc_out),
118 	word		* x,		/* [0..39]		IN  */
119 	word		* xM,		/* [0..12]		OUT */
120 	word		* Mc_out	/*			OUT */
121 )
122 /*
123  *  The signal x[0..39] is used to select the RPE grid which is
124  *  represented by Mc.
125  */
126 {
127 	/* register word	temp1;	*/
128 	register int		/* m, */  i;
129 	register longword	L_result, L_temp;
130 	longword		EM;	/* xxx should be L_EM? */
131 	word			Mc;
132 
133 	longword		L_common_0_3;
134 
135 	EM = 0;
136 	Mc = 0;
137 
138 	/* for (m = 0; m <= 3; m++) {
139 	 *	L_result = 0;
140 	 *
141 	 *
142 	 *	for (i = 0; i <= 12; i++) {
143 	 *
144 	 *		temp1    = SASR( x[m + 3*i], 2 );
145 	 *
146 	 *		assert(temp1 != MIN_WORD);
147 	 *
148 	 *		L_temp   = GSM_L_MULT( temp1, temp1 );
149 	 *		L_result = GSM_L_ADD( L_temp, L_result );
150 	 *	}
151 	 *
152 	 *	if (L_result > EM) {
153 	 *		Mc = m;
154 	 *		EM = L_result;
155 	 *	}
156 	 * }
157 	 */
158 
159 #undef	STEP
160 #define	STEP( m, i )		L_temp = SASR( x[m + 3 * i], 2 );	\
161 				L_result += L_temp * L_temp;
162 
163 	/* common part of 0 and 3 */
164 
165 	L_result = 0;
166 	STEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 );
167 	STEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 );
168 	STEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12);
169 	L_common_0_3 = L_result;
170 
171 	/* i = 0 */
172 
173 	STEP( 0, 0 );
174 	L_result <<= 1;	/* implicit in L_MULT */
175 	EM = L_result;
176 
177 	/* i = 1 */
178 
179 	L_result = 0;
180 	STEP( 1, 0 );
181 	STEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 );
182 	STEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 );
183 	STEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12);
184 	L_result <<= 1;
185 	if (L_result > EM) {
186 		Mc = 1;
187 	 	EM = L_result;
188 	}
189 
190 	/* i = 2 */
191 
192 	L_result = 0;
193 	STEP( 2, 0 );
194 	STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 );
195 	STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 );
196 	STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12);
197 	L_result <<= 1;
198 	if (L_result > EM) {
199 		Mc = 2;
200 	 	EM = L_result;
201 	}
202 
203 	/* i = 3 */
204 
205 	L_result = L_common_0_3;
206 	STEP( 3, 12 );
207 	L_result <<= 1;
208 	if (L_result > EM) {
209 		Mc = 3;
210 	 	EM = L_result;
211 	}
212 
213 	/**/
214 
215 	/*  Down-sampling by a factor 3 to get the selected xM[0..12]
216 	 *  RPE sequence.
217 	 */
218 	for (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i];
219 	*Mc_out = Mc;
220 }
221 
222 /* 4.12.15 */
223 
224 static void APCM_quantization_xmaxc_to_exp_mant P3((xmaxc,exp_out,mant_out),
225 	word		xmaxc,		/* IN 	*/
226 	word		* exp_out,	/* OUT	*/
227 	word		* mant_out )	/* OUT  */
228 {
229 	word	exp, mant;
230 
231 	/* Compute exponent and mantissa of the decoded version of xmaxc
232 	 */
233 
234 	exp = 0;
235 	if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1;
236 	mant = xmaxc - (exp << 3);
237 
238 	if (mant == 0) {
239 		exp  = -4;
240 		mant = 7;
241 	}
242 	else {
243 		while (mant <= 7) {
244 			mant = mant << 1 | 1;
245 			exp--;
246 		}
247 		mant -= 8;
248 	}
249 
250 	assert( exp  >= -4 && exp <= 6 );
251 	assert( mant >= 0 && mant <= 7 );
252 
253 	*exp_out  = exp;
254 	*mant_out = mant;
255 }
256 
257 static void APCM_quantization P5((xM,xMc,mant_out,exp_out,xmaxc_out),
258 	word		* xM,		/* [0..12]		IN	*/
259 
260 	word		* xMc,		/* [0..12]		OUT	*/
261 	word		* mant_out,	/* 			OUT	*/
262 	word		* exp_out,	/*			OUT	*/
263 	word		* xmaxc_out	/*			OUT	*/
264 )
265 {
266 	int	i, itest;
267 
268 	word	xmax, xmaxc, temp, temp1, temp2;
269 	word	exp, mant;
270 
271 
272 	/*  Find the maximum absolute value xmax of xM[0..12].
273 	 */
274 
275 	xmax = 0;
276 	for (i = 0; i <= 12; i++) {
277 		temp = xM[i];
278 		temp = GSM_ABS(temp);
279 		if (temp > xmax) xmax = temp;
280 	}
281 
282 	/*  Qantizing and coding of xmax to get xmaxc.
283 	 */
284 
285 	exp   = 0;
286 	temp  = SASR( xmax, 9 );
287 	itest = 0;
288 
289 	for (i = 0; i <= 5; i++) {
290 
291 		itest |= (temp <= 0);
292 		temp = SASR( temp, 1 );
293 
294 		assert(exp <= 5);
295 		if (itest == 0) exp++;		/* exp = add (exp, 1) */
296 	}
297 
298 	assert(exp <= 6 && exp >= 0);
299 	temp = exp + 5;
300 
301 	assert(temp <= 11 && temp >= 0);
302 	xmaxc = gsm_add( SASR(xmax, temp), exp << 3 );
303 
304 	/*   Quantizing and coding of the xM[0..12] RPE sequence
305 	 *   to get the xMc[0..12]
306 	 */
307 
308 	APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant );
309 
310 	/*  This computation uses the fact that the decoded version of xmaxc
311 	 *  can be calculated by using the exponent and the mantissa part of
312 	 *  xmaxc (logarithmic table).
313 	 *  So, this method avoids any division and uses only a scaling
314 	 *  of the RPE samples by a function of the exponent.  A direct
315 	 *  multiplication by the inverse of the mantissa (NRFAC[0..7]
316 	 *  found in table 4.5) gives the 3 bit coded version xMc[0..12]
317 	 *  of the RPE samples.
318 	 */
319 
320 
321 	/* Direct computation of xMc[0..12] using table 4.5
322 	 */
323 
324 	assert( exp <= 4096 && exp >= -4096);
325 	assert( mant >= 0 && mant <= 7 );
326 
327 	temp1 = 6 - exp;		/* normalization by the exponent */
328 	temp2 = gsm_NRFAC[ mant ];  	/* inverse mantissa 		 */
329 
330 	for (i = 0; i <= 12; i++) {
331 
332 		assert(temp1 >= 0 && temp1 < 16);
333 
334 		temp = xM[i] << temp1;
335 		temp = GSM_MULT( temp, temp2 );
336 		temp = SASR(temp, 12);
337 		xMc[i] = temp + 4;		/* see note below */
338 	}
339 
340 	/*  NOTE: This equation is used to make all the xMc[i] positive.
341 	 */
342 
343 	*mant_out  = mant;
344 	*exp_out   = exp;
345 	*xmaxc_out = xmaxc;
346 }
347 
348 /* 4.2.16 */
349 
350 static void APCM_inverse_quantization P4((xMc,mant,exp,xMp),
351 	register word	* xMc,	/* [0..12]			IN 	*/
352 	word		mant,
353 	word		exp,
354 	register word	* xMp)	/* [0..12]			OUT 	*/
355 /*
356  *  This part is for decoding the RPE sequence of coded xMc[0..12]
357  *  samples to obtain the xMp[0..12] array.  Table 4.6 is used to get
358  *  the mantissa of xmaxc (FAC[0..7]).
359  */
360 {
361 	int	i;
362 	word	temp, temp1, temp2, temp3;
363 	longword	ltmp;
364 
365 	assert( mant >= 0 && mant <= 7 );
366 
367 	temp1 = gsm_FAC[ mant ];	/* see 4.2-15 for mant */
368 	temp2 = gsm_sub( 6, exp );	/* see 4.2-15 for exp  */
369 	temp3 = gsm_asl( 1, gsm_sub( temp2, 1 ));
370 
371 	for (i = 13; i--;) {
372 
373 		assert( *xMc <= 7 && *xMc >= 0 ); 	/* 3 bit unsigned */
374 
375 		/* temp = gsm_sub( *xMc++ << 1, 7 ); */
376 		temp = (*xMc++ << 1) - 7;	        /* restore sign   */
377 		assert( temp <= 7 && temp >= -7 ); 	/* 4 bit signed   */
378 
379 		temp <<= 12;				/* 16 bit signed  */
380 		temp = GSM_MULT_R( temp1, temp );
381 		temp = (word) GSM_ADD( temp, temp3 );
382 		*xMp++ = gsm_asr( temp, temp2 );
383 	}
384 }
385 
386 /* 4.2.17 */
387 
388 static void RPE_grid_positioning P3((Mc,xMp,ep),
389 	word		Mc,		/* grid position	IN	*/
390 	register word	* xMp,		/* [0..12]		IN	*/
391 	register word	* ep		/* [0..39]		OUT	*/
392 )
393 /*
394  *  This procedure computes the reconstructed long term residual signal
395  *  ep[0..39] for the LTP analysis filter.  The inputs are the Mc
396  *  which is the grid position selection and the xMp[0..12] decoded
397  *  RPE samples which are upsampled by a factor of 3 by inserting zero
398  *  values.
399  */
400 {
401 	int	i = 13;
402 
403 	assert(0 <= Mc && Mc <= 3);
404 
405         switch (Mc) {
406                 case 3: *ep++ = 0;
407                 case 2:  do {
408                                 *ep++ = 0;
409                 case 1:         *ep++ = 0;
410                 case 0:         *ep++ = *xMp++;
411                          } while (--i);
412         }
413         while (++Mc < 4) *ep++ = 0;
414 
415 	/*
416 
417 	int i, k;
418 	for (k = 0; k <= 39; k++) ep[k] = 0;
419 	for (i = 0; i <= 12; i++) {
420 		ep[ Mc + (3*i) ] = xMp[i];
421 	}
422 	*/
423 }
424 
425 /* 4.2.18 */
426 
427 /*  This procedure adds the reconstructed long term residual signal
428  *  ep[0..39] to the estimated signal dpp[0..39] from the long term
429  *  analysis filter to compute the reconstructed short term residual
430  *  signal dp[-40..-1]; also the reconstructed short term residual
431  *  array dp[-120..-41] is updated.
432  */
433 
434 #if 0	/* Has been inlined in code.c */
435 void Gsm_Update_of_reconstructed_short_time_residual_signal P3((dpp, ep, dp),
436 	word	* dpp,		/* [0...39]	IN	*/
437 	word	* ep,		/* [0...39]	IN	*/
438 	word	* dp)		/* [-120...-1]  IN/OUT 	*/
439 {
440 	int 		k;
441 
442 	for (k = 0; k <= 79; k++)
443 		dp[ -120 + k ] = dp[ -80 + k ];
444 
445 	for (k = 0; k <= 39; k++)
446 		dp[ -40 + k ] = gsm_add( ep[k], dpp[k] );
447 }
448 #endif	/* Has been inlined in code.c */
449 
450 void Gsm_RPE_Encoding P5((S,e,xmaxc,Mc,xMc),
451 
452 	struct gsm_state * S,
453 
454 	word	* e,		/* -5..-1][0..39][40..44	IN/OUT  */
455 	word	* xmaxc,	/* 				OUT */
456 	word	* Mc,		/* 			  	OUT */
457 	word	* xMc)		/* [0..12]			OUT */
458 {
459 	word	x[40];
460 	word	xM[13], xMp[13];
461 	word	mant, exp;
462 
463 	Weighting_filter(e, x);
464 	RPE_grid_selection(x, xM, Mc);
465 
466 	APCM_quantization(	xM, xMc, &mant, &exp, xmaxc);
467 	APCM_inverse_quantization(  xMc,  mant,  exp, xMp);
468 
469 	RPE_grid_positioning( *Mc, xMp, e );
470 
471 }
472 
473 void Gsm_RPE_Decoding P5((S, xmaxcr, Mcr, xMcr, erp),
474 	struct gsm_state	* S,
475 
476 	word 		xmaxcr,
477 	word		Mcr,
478 	word		* xMcr,  /* [0..12], 3 bits 		IN	*/
479 	word		* erp	 /* [0..39]			OUT 	*/
480 )
481 {
482 	word	exp, mant;
483 	word	xMp[ 13 ];
484 
485 	APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant );
486 	APCM_inverse_quantization( xMcr, mant, exp, xMp );
487 	RPE_grid_positioning( Mcr, xMp, erp );
488 
489 }
490