set_sign.cpp revision e55147f462e04d41bff7ead6e9ea61a5b83bda4b
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/****************************************************************************************
19Portions 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)
26Permission to distribute, modify and use this file under the standard license
27terms 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
170void 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
245void 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    register 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
357void 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
486void 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