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