1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
20
21 3GPP TS 26.073
22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23 Available from http://www.3gpp.org
24
25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
29 /*
30 ------------------------------------------------------------------------------
31
32
33
34 Pathname: ./audio/gsm-amr/c/src/set_sign.c
35 Funtions: set_sign
36 set_sign12k2
37
38 Date: 05/26/2000
39
40 ------------------------------------------------------------------------------
41 REVISION HISTORY
42
43 Description: Placed into PV template and optimized.
44
45 Description: Synchronized file with UMTS version 3.2.0. Updated coding
46 template. Removed unnecessary include files.
47
48 Description: Replaced basic_op.h with the header files of the math functions
49 used in the file.
50
51 Description: Made the following changes per comments from Phase 2/3 review:
52 1. Modified certain FOR loops to count down.
53 2. Modified code for further optimization.
54
55 Description: Modified FOR loops in set_sign12k2 to count up. The FOR loops
56 affected are the loop that calculates the starting position of
57 each incoming pulse, and the loop that calculates the position
58 of the max correlation. Updated copyright year.
59
60 Description: Passing in pointer to overflow flag for EPOC compatibility.
61
62 Description: For set_sign12k2()
63 1. Eliminated unused include files.
64 2. Replaced array addressing by pointers
65 3. Eliminated math operations that unnecessary checked for
66 saturation, this by evaluating the operands
67 4. Replaced loop counter with decrement loops
68
69 Description: Replaced "int" and/or "char" with OSCL defined types.
70
71 Description: Changed round function name to pv_round to avoid conflict with
72 round function in C standard library.
73
74 Description:
75
76 ------------------------------------------------------------------------------
77 MODULE DESCRIPTION
78
79 This module contains the functions set_sign and set_sign12k2.
80 These functions are used to build a sign vector according
81 to the values in the input arrays. These functions also
82 find the position in the input codes of the maximum correlation
83 and the starting position for each pulse.
84
85 ------------------------------------------------------------------------------
86 */
87
88
89 /*----------------------------------------------------------------------------
90 ; INCLUDES
91 ----------------------------------------------------------------------------*/
92 #include "set_sign.h"
93 #include "basic_op.h"
94 #include "inv_sqrt.h"
95 #include "cnst.h"
96
97
98 /*----------------------------------------------------------------------------
99 ; MACROS
100 ; Define module specific macros here
101 ----------------------------------------------------------------------------*/
102
103
104 /*----------------------------------------------------------------------------
105 ; DEFINES
106 ; Include all pre-processor statements here. Include conditional
107 ; compile variables also.
108 ----------------------------------------------------------------------------*/
109
110 /*----------------------------------------------------------------------------
111 ; LOCAL FUNCTION DEFINITIONS
112 ; Function Prototype declaration
113 ----------------------------------------------------------------------------*/
114
115 /*----------------------------------------------------------------------------
116 ; LOCAL VARIABLE DEFINITIONS
117 ; Variable declaration - defined here and used outside this module
118 ----------------------------------------------------------------------------*/
119
120
121 /*
122 ------------------------------------------------------------------------------
123 FUNCTION NAME: set_sign
124 ------------------------------------------------------------------------------
125 INPUT AND OUTPUT DEFINITIONS
126
127 Inputs:
128 dn = buffer of correlation values (Word16)
129 sign = buffer containing sign of dn elements (Word16)
130 dn2 = buffer containing the maximum of correlation in each track.(Word16)
131 n = number of maximum correlations in dn2 (Word16)
132
133 Returns:
134 None
135
136 Outputs:
137 dn buffer is modified to contain the absolute value of its input
138 sign buffer is modified to contain the sign information for the
139 values in dn buffer
140 dn2 buffer is modified to denote the location of the maximum
141 correlation for each track.
142
143 Global Variables Used:
144 None
145
146 Local Variables Needed:
147 None
148
149 ------------------------------------------------------------------------------
150 FUNCTION DESCRIPTION
151
152
153 This function builds sign vector according to dn buffer It also finds
154 the position of maximum of correlation in each track and the starting
155 position for each pulse.
156
157 ------------------------------------------------------------------------------
158 REQUIREMENTS
159
160 None.
161
162 ------------------------------------------------------------------------------
163 REFERENCES
164
165 set_sign.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
166
167 ------------------------------------------------------------------------------
168 PSEUDO-CODE
169
170 void set_sign(Word16 dn[], i/o : correlation between target and h[]
171 Word16 sign[], o : sign of dn[]
172 Word16 dn2[], o : maximum of correlation in each track.
173 Word16 n i : # of maximum correlations in dn2[]
174 )
175 {
176 Word16 i, j, k;
177 Word16 val, min;
178 Word16 pos = 0; //initialization only needed to keep gcc silent
179
180 // set sign according to dn[]
181
182 for (i = 0; i < L_CODE; i++) {
183 val = dn[i];
184
185 if (val >= 0) {
186 sign[i] = 32767;
187 } else {
188 sign[i] = -32767;
189 val = negate(val);
190 }
191 dn[i] = val; // modify dn[] according to the fixed sign
192 dn2[i] = val;
193 }
194
195 // keep 8-n maximum positions/8 of each track and store it in dn2[]
196
197 for (i = 0; i < NB_TRACK; i++)
198 {
199 for (k = 0; k < (8-n); k++)
200 {
201 min = 0x7fff;
202 for (j = i; j < L_CODE; j += STEP)
203 {
204 if (dn2[j] >= 0)
205 {
206 val = sub(dn2[j], min);
207
208 if (val < 0)
209 {
210 min = dn2[j];
211 pos = j;
212 }
213 }
214 }
215 dn2[pos] = -1;
216 }
217 }
218
219 return;
220 }
221
222 ------------------------------------------------------------------------------
223 RESOURCES USED [optional]
224
225 When the code is written for a specific target processor the
226 the resources used should be documented below.
227
228 HEAP MEMORY USED: x bytes
229
230 STACK MEMORY USED: x bytes
231
232 CLOCK CYCLES: (cycle count equation for this function) + (variable
233 used to represent cycle count for each subroutine
234 called)
235 where: (cycle count variable) = cycle count for [subroutine
236 name]
237
238 ------------------------------------------------------------------------------
239 CAUTION [optional]
240 [State any special notes, constraints or cautions for users of this function]
241
242 ------------------------------------------------------------------------------
243 */
244
set_sign(Word16 dn[],Word16 sign[],Word16 dn2[],Word16 n)245 void set_sign(Word16 dn[], /* i/o : correlation between target and h[] */
246 Word16 sign[], /* o : sign of dn[] */
247 Word16 dn2[], /* o : maximum of correlation in each track. */
248 Word16 n /* i : # of maximum correlations in dn2[] */
249 )
250 {
251 Word16 i, j, k;
252 Word16 val, min;
253 Word16 pos = 0; /* initialization only needed to keep gcc silent */
254
255 /* set sign according to dn[] */
256 for (i = L_CODE - 1; i >= 0; i--)
257 {
258 val = dn[i];
259
260 if (val >= 0)
261 {
262 sign[i] = 32767;
263 }
264 else
265 {
266 sign[i] = -32767;
267 val = negate(val);
268 dn[i] = val; /* modify dn[] according to the fixed sign */
269 }
270
271 dn2[i] = val;
272 }
273
274 /* keep 8-n maximum positions/8 of each track and store it in dn2[] */
275
276 for (i = 0; i < NB_TRACK; i++)
277 {
278 for (k = 0; k < (8 - n); k++)
279 {
280 min = 0x7fff;
281 for (j = i; j < L_CODE; j += STEP)
282 {
283 if (dn2[j] >= 0)
284 {
285 if (dn2[j] < min)
286 {
287 min = dn2[j];
288 pos = j;
289 }
290 }
291 }
292 dn2[pos] = -1;
293 }
294 }
295
296 return;
297 }
298
299 /****************************************************************************/
300
301
302 /*
303 ------------------------------------------------------------------------------
304 FUNCTION NAME: set_sign12k2()
305 ------------------------------------------------------------------------------
306 INPUT AND OUTPUT DEFINITIONS
307
308 Inputs:
309 dn = buffer of correlation values (Word16)
310 cn = buffer of residual after long term prediction (Word16)
311 sign = sign of correlation buffer elements (Word16)
312 pos_max = buffer containing position of maximum correlation (Word16)
313 nb_track = number of tracks (Word16)
314 ipos = buffer containing the starting position for each pulse (Word16)
315 step = step size in the tracks (Word16)
316 pOverflow = pointer to Overflow flag (Flag)
317
318 Outputs:
319 sign buffer contains the sign of correlation values
320 dn buffer contains the sign-adjusted correlation values
321 pos_max buffer contains the maximum correlation position
322 ipos buffer contains the starting position of each pulse
323 pOverflow -> 1 if the math operations called by this function result in
324 saturation
325
326
327 Returns:
328 None
329
330 Global Variables Used:
331 None
332
333 Local Variables Needed:
334 None
335
336 ------------------------------------------------------------------------------
337 FUNCTION DESCRIPTION
338
339 This function builds the sign vector according to dn and cn, and modifies
340 dn to include the sign information (dn[i]=sign[i]*dn[i]). It also finds
341 the position of maximum of correlation in each track and the starting
342 position for each pulse.
343
344 ------------------------------------------------------------------------------
345 REQUIREMENTS
346
347 None
348
349 ------------------------------------------------------------------------------
350 REFERENCES
351
352 set_sign.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
353
354 ------------------------------------------------------------------------------
355 PSEUDO-CODE
356
357 void set_sign12k2 (
358 Word16 dn[], //i/o : correlation between target and h[]
359 Word16 cn[], //i : residual after long term prediction
360 Word16 sign[], //o : sign of d[n]
361 Word16 pos_max[], //o : position of maximum correlation
362 Word16 nb_track, //i : number of tracks tracks
363 Word16 ipos[], //o : starting position for each pulse
364 Word16 step //i : the step size in the tracks
365 )
366 {
367 Word16 i, j;
368 Word16 val, cor, k_cn, k_dn, max, max_of_all;
369 Word16 pos = 0; // initialization only needed to keep gcc silent
370 Word16 en[L_CODE]; // correlation vector
371 Word32 s;
372
373 // The reference ETSI code uses a global flag for Overflow. However in the
374 // actual implementation a pointer to the overflow flag is passed in. This
375 // pointer is passed into the basic math functions called by this routine.
376
377 // calculate energy for normalization of cn[] and dn[]
378
379 s = 256;
380 for (i = 0; i < L_CODE; i++)
381 {
382 s = L_mac (s, cn[i], cn[i]);
383 }
384 s = Inv_sqrt (s);
385 k_cn = extract_h (L_shl (s, 5));
386
387 s = 256;
388 for (i = 0; i < L_CODE; i++)
389 {
390 s = L_mac (s, dn[i], dn[i]);
391 }
392 s = Inv_sqrt (s);
393 k_dn = extract_h (L_shl (s, 5));
394
395 for (i = 0; i < L_CODE; i++)
396 {
397 val = dn[i];
398 cor = pv_round (L_shl (L_mac (L_mult (k_cn, cn[i]), k_dn, val), 10));
399
400 if (cor >= 0)
401 {
402 sign[i] = 32767; // sign = +1
403 }
404 else
405 {
406 sign[i] = -32767; // sign = -1
407 cor = negate (cor);
408 val = negate (val);
409 }
410 // modify dn[] according to the fixed sign
411 dn[i] = val;
412 en[i] = cor;
413 }
414
415 max_of_all = -1;
416 for (i = 0; i < nb_track; i++)
417 {
418 max = -1;
419
420 for (j = i; j < L_CODE; j += step)
421 {
422 cor = en[j];
423 val = sub (cor, max);
424
425 if (val > 0)
426 {
427 max = cor;
428 pos = j;
429 }
430 }
431 // store maximum correlation position
432 pos_max[i] = pos;
433 val = sub (max, max_of_all);
434
435 if (val > 0)
436 {
437 max_of_all = max;
438 // starting position for i0
439 ipos[0] = i;
440 }
441 }
442
443 //
444 // Set starting position of each pulse.
445 //
446
447 pos = ipos[0];
448 ipos[nb_track] = pos;
449
450 for (i = 1; i < nb_track; i++)
451 {
452 pos = add (pos, 1);
453
454 if (sub (pos, nb_track) >= 0)
455 {
456 pos = 0;
457 }
458 ipos[i] = pos;
459 ipos[add(i, nb_track)] = pos;
460 }
461 }
462
463 ------------------------------------------------------------------------------
464 RESOURCES USED [optional]
465
466 When the code is written for a specific target processor the
467 the resources used should be documented below.
468
469 HEAP MEMORY USED: x bytes
470
471 STACK MEMORY USED: x bytes
472
473 CLOCK CYCLES: (cycle count equation for this function) + (variable
474 used to represent cycle count for each subroutine
475 called)
476 where: (cycle count variable) = cycle count for [subroutine
477 name]
478
479 ------------------------------------------------------------------------------
480 CAUTION [optional]
481 [State any special notes, constraints or cautions for users of this function]
482
483 ------------------------------------------------------------------------------
484 */
485
set_sign12k2(Word16 dn[],Word16 cn[],Word16 sign[],Word16 pos_max[],Word16 nb_track,Word16 ipos[],Word16 step,Flag * pOverflow)486 void set_sign12k2(
487 Word16 dn[], /* i/o : correlation between target and h[] */
488 Word16 cn[], /* i : residual after long term prediction */
489 Word16 sign[], /* o : sign of d[n] */
490 Word16 pos_max[], /* o : position of maximum correlation */
491 Word16 nb_track, /* i : number of tracks tracks */
492 Word16 ipos[], /* o : starting position for each pulse */
493 Word16 step, /* i : the step size in the tracks */
494 Flag *pOverflow /* i/o: overflow flag */
495 )
496 {
497 Word16 i, j;
498 Word16 val;
499 Word16 cor;
500 Word16 k_cn;
501 Word16 k_dn;
502 Word16 max;
503 Word16 max_of_all;
504 Word16 pos = 0; /* initialization only needed to keep gcc silent */
505 Word16 en[L_CODE]; /* correlation vector */
506 Word32 s;
507 Word32 t;
508 Word32 L_temp;
509 Word16 *p_cn;
510 Word16 *p_dn;
511 Word16 *p_sign;
512 Word16 *p_en;
513
514 /* calculate energy for normalization of cn[] and dn[] */
515
516 s = 256;
517 t = 256;
518 p_cn = cn;
519 p_dn = dn; /* crosscorrelation values do not have strong peaks, so
520 scaling applied in cor_h_x (sf=2) guaranteed that the
521 mac of the energy for this vector will not overflow */
522
523 for (i = L_CODE; i != 0; i--)
524 {
525 val = *(p_cn++);
526 s = L_mac(s, val, val, pOverflow);
527 val = *(p_dn++);
528 t += ((Word32) val * val) << 1;
529 }
530 s = Inv_sqrt(s, pOverflow);
531 k_cn = (Word16)((L_shl(s, 5, pOverflow)) >> 16);
532
533 t = Inv_sqrt(t, pOverflow);
534 k_dn = (Word16)(t >> 11);
535
536 p_cn = &cn[L_CODE-1];
537 p_sign = &sign[L_CODE-1];
538 p_en = &en[L_CODE-1];
539
540 for (i = L_CODE - 1; i >= 0; i--)
541 {
542 L_temp = ((Word32)k_cn * *(p_cn--)) << 1;
543 val = dn[i];
544 s = L_mac(L_temp, k_dn, val, pOverflow);
545 L_temp = L_shl(s, 10, pOverflow);
546 cor = pv_round(L_temp, pOverflow);
547
548 if (cor >= 0)
549 {
550 *(p_sign--) = 32767; /* sign = +1 */
551 }
552 else
553 {
554 *(p_sign--) = -32767; /* sign = -1 */
555 cor = negate(cor);
556
557 /* modify dn[] according to the fixed sign */
558 dn[i] = negate(val);
559 }
560
561 *(p_en--) = cor;
562 }
563
564 max_of_all = -1;
565 for (i = 0; i < nb_track; i++)
566 {
567 max = -1;
568
569 for (j = i; j < L_CODE; j += step)
570 {
571 cor = en[j];
572 if (cor > max)
573 {
574 max = cor;
575 pos = j;
576 }
577 }
578 /* store maximum correlation position */
579 pos_max[i] = pos;
580 if (max > max_of_all)
581 {
582 max_of_all = max;
583 /* starting position for i0 */
584 ipos[0] = i;
585 }
586 }
587
588 /*----------------------------------------------------------------*
589 * Set starting position of each pulse. *
590 *----------------------------------------------------------------*/
591
592 pos = ipos[0];
593 ipos[nb_track] = pos;
594
595 for (i = 1; i < nb_track; i++)
596 {
597 pos++;
598
599 if (pos >= nb_track)
600 {
601 pos = 0;
602 }
603 ipos[ i] = pos;
604 ipos[ i + nb_track] = pos;
605 }
606
607 return;
608 }
609
610