• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/c2_11pf.c
35   Functions:
36              code_2i40_11bits
37              search_2i40
38              build_code
39  
40       Date: 01/28/2002
41  
42  ------------------------------------------------------------------------------
43   REVISION HISTORY
44  
45   Description: Modified to pass overflow flag through to basic math function.
46   The flag is passed back to the calling function by pointer reference.
47  
48   Description: Fixed tabs prior to optimization to make diff'ing easier.
49                Optimized search_2i40() to reduce clock cycle usage.
50  
51   Description: Optimized build_code() to reduce clock cycle usage.
52  
53   Description: Changed function name to pv_round to avoid conflict with
54                round function in C standard library.
55  
56   Description:  Added casting to eliminate warnings
57  
58   Description:  Replaced "int" and/or "char" with OSCL defined types.
59  
60   Description:
61  
62  ------------------------------------------------------------------------------
63   MODULE DESCRIPTION
64  
65   *************************************************************************
66   *
67   *  FUNCTION:  code_2i40_11bits()
68   *
69   *  PURPOSE:  Searches a 11 bit algebraic codebook containing 2 pulses
70   *            in a frame of 40 samples.
71   *
72   *  DESCRIPTION:
73   *    The code length is 40, containing 2 nonzero pulses: i0...i1.
74   *    All pulses can have two possible amplitudes: +1 or -1.
75   *    Pulse i0 can have 2x8=16 possible positions, pulse i1 can have
76   *    4x8=32 positions.
77   *
78   *       i0 :  1, 6, 11, 16, 21, 26, 31, 36.
79   *             3, 8, 13, 18, 23, 28, 33, 38.
80   *       i1 :  0, 5, 10, 15, 20, 25, 30, 35.
81   *             1, 6, 11, 16, 21, 26, 31, 36.
82   *             2, 7, 12, 17, 22, 27, 32, 37.
83   *             4, 9, 14, 19, 24, 29, 34, 39.
84   *
85   *************************************************************************
86  ------------------------------------------------------------------------------
87  */
88  
89  /*----------------------------------------------------------------------------
90  ; INCLUDES
91  ----------------------------------------------------------------------------*/
92  #include "c2_11pf.h"
93  #include "typedef.h"
94  #include "basic_op.h"
95  #include "inv_sqrt.h"
96  #include "cnst.h"
97  #include "cor_h.h"
98  #include "set_sign.h"
99  
100  /*----------------------------------------------------------------------------
101  ; MACROS
102  ; Define module specific macros here
103  ----------------------------------------------------------------------------*/
104  
105  /*----------------------------------------------------------------------------
106  ; DEFINES
107  ; Include all pre-processor statements here. Include conditional
108  ; compile variables also.
109  ----------------------------------------------------------------------------*/
110  #define NB_PULSE  2
111  
112  #define _1_2    (Word16)(32768L/2)
113  #define _1_4    (Word16)(32768L/4)
114  #define _1_8    (Word16)(32768L/8)
115  #define _1_16   (Word16)(32768L/16)
116  
117  /*----------------------------------------------------------------------------
118  ; LOCAL FUNCTION DEFINITIONS
119  ; Function Prototype declaration
120  ----------------------------------------------------------------------------*/
121  static void search_2i40(
122      Word16 dn[],        /* i : correlation between target and h[]            */
123      Word16 rr[][L_CODE],/* i : matrix of autocorrelation                     */
124      Word16 codvec[],    /* o : algebraic codebook vector                     */
125      Flag   * pOverflow
126  );
127  
128  static Word16 build_code(
129      Word16 codvec[],    /* i : algebraic codebook vector                     */
130      Word16 dn_sign[],   /* i : sign of dn[]                                  */
131      Word16 cod[],       /* o : algebraic (fixed) codebook excitation         */
132      Word16 h[],         /* i : impulse response of weighted synthesis filter */
133      Word16 y[],         /* o : filtered fixed codebook excitation            */
134      Word16 sign[],      /* o : sign of 2 pulses                              */
135      Flag   * pOverflow
136  );
137  
138  /*----------------------------------------------------------------------------
139  ; LOCAL VARIABLE DEFINITIONS
140  ; Variable declaration - defined here and used outside this module
141  ----------------------------------------------------------------------------*/
142  
143  const Word16 startPos1[2] = {1, 3};
144  const Word16 startPos2[4] = {0, 1, 2, 4};
145  
146  /*
147  ------------------------------------------------------------------------------
148   FUNCTION NAME: code_2i40_11bits
149  ------------------------------------------------------------------------------
150   INPUT AND OUTPUT DEFINITIONS
151  
152   Inputs:
153      x,  target vector, array of type Word16
154      h,  impulse response of weighted synthesis filter, array of type Word16
155      T0, Pitch lag, variable of type Word16
156      pitch_sharp, Last quantized pitch gain, variable of type Word16
157  
158   Outputs:
159      code[], Innovative codebook, array of type Word16
160      y[],    filtered fixed codebook excitation, array of type Word16
161      sign,   Signs of 2 pulses, pointer of type Word16 *
162      pOverflow  Flag set when overflow occurs, pointer of type Flag *
163  
164   Returns:
165      index
166  
167   Global Variables Used:
168      None
169  
170   Local Variables Needed:
171      None
172  
173  ------------------------------------------------------------------------------
174   FUNCTION DESCRIPTION
175  
176       Searches a 11 bit algebraic codebook containing 2 pulses
177       in a frame of 40 samples.
178  
179       The code length is 40, containing 2 nonzero pulses: i0...i1.
180       All pulses can have two possible amplitudes: +1 or -1.
181       Pulse i0 can have 2x8=16 possible positions, pulse i1 can have
182       4x8=32 positions.
183  
184          i0 :  1, 6, 11, 16, 21, 26, 31, 36.
185                3, 8, 13, 18, 23, 28, 33, 38.
186          i1 :  0, 5, 10, 15, 20, 25, 30, 35.
187                1, 6, 11, 16, 21, 26, 31, 36.
188                2, 7, 12, 17, 22, 27, 32, 37.
189                4, 9, 14, 19, 24, 29, 34, 39.
190  
191  ------------------------------------------------------------------------------
192   REQUIREMENTS
193  
194   None
195  
196  ------------------------------------------------------------------------------
197   REFERENCES
198  
199   c2_11pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
200  
201  ------------------------------------------------------------------------------
202   PSEUDO-CODE
203  
204  
205  ------------------------------------------------------------------------------
206   RESOURCES USED [optional]
207  
208   When the code is written for a specific target processor the
209   the resources used should be documented below.
210  
211   HEAP MEMORY USED: x bytes
212  
213   STACK MEMORY USED: x bytes
214  
215   CLOCK CYCLES: (cycle count equation for this function) + (variable
216                  used to represent cycle count for each subroutine
217                  called)
218       where: (cycle count variable) = cycle count for [subroutine
219                                       name]
220  
221  ------------------------------------------------------------------------------
222   CAUTION [optional]
223   [State any special notes, constraints or cautions for users of this function]
224  
225  ------------------------------------------------------------------------------
226  */
code_2i40_11bits(Word16 x[],Word16 h[],Word16 T0,Word16 pitch_sharp,Word16 code[],Word16 y[],Word16 * sign,Flag * pOverflow)227  Word16 code_2i40_11bits(
228      Word16 x[],         /* i : target vector                                 */
229      Word16 h[],         /* i : impulse response of weighted synthesis filter */
230      /*     h[-L_subfr..-1] must be set to zero.          */
231      Word16 T0,          /* i : Pitch lag                                     */
232      Word16 pitch_sharp, /* i : Last quantized pitch gain                     */
233      Word16 code[],      /* o : Innovative codebook                           */
234      Word16 y[],         /* o : filtered fixed codebook excitation            */
235      Word16 * sign,      /* o : Signs of 2 pulses                             */
236      Flag   * pOverflow  /* o : Flag set when overflow occurs                 */
237  )
238  {
239      Word16 codvec[NB_PULSE];
240      Word16 dn[L_CODE];
241      Word16 dn2[L_CODE];
242      Word16 dn_sign[L_CODE];
243  
244      Word16 rr[L_CODE][L_CODE];
245  
246      Word16 i;
247      Word16 index;
248      Word16 sharp;
249      Word16 tempWord;
250  
251      sharp = pitch_sharp << 1;
252  
253      if (T0 < L_CODE)
254      {
255          for (i = T0; i < L_CODE; i++)
256          {
257              tempWord =
258                  mult(
259                      h[i - T0],
260                      sharp,
261                      pOverflow);
262  
263              h[i] =
264                  add(
265                      h[i],
266                      tempWord,
267                      pOverflow);
268          }
269  
270      }
271  
272      cor_h_x(
273          h,
274          x,
275          dn,
276          1,
277          pOverflow);
278  
279      set_sign(
280          dn,
281          dn_sign,
282          dn2,
283          8); /* dn2[] not used in this codebook search */
284  
285      cor_h(
286          h,
287          dn_sign,
288          rr,
289          pOverflow);
290  
291      search_2i40(
292          dn,
293          rr,
294          codvec,
295          pOverflow);
296  
297      /* function result */
298  
299      index =
300          build_code(
301              codvec,
302              dn_sign,
303              code,
304              h,
305              y,
306              sign,
307              pOverflow);
308  
309      /*
310      * Compute innovation vector gain.
311      * Include fixed-gain pitch contribution into code[].
312      */
313  
314      if (T0 < L_CODE)
315      {
316          for (i = T0; i < L_CODE; i++)
317          {
318              tempWord =
319                  mult(
320                      code[i - T0],
321                      sharp,
322                      pOverflow);
323  
324              code[i] =
325                  add(
326                      code[i],
327                      tempWord,
328                      pOverflow);
329          }
330      }
331  
332      return index;
333  }
334  
335  /****************************************************************************/
336  
337  
338  /*
339  ------------------------------------------------------------------------------
340   FUNCTION NAME: search_2i40
341  ------------------------------------------------------------------------------
342   INPUT AND OUTPUT DEFINITIONS
343  
344   Inputs:
345      dn, correlation between target and h[], array of type Word16
346      rr, matrix of autocorrelation, double-array of type Word16
347  
348   Outputs:
349      codvec[],  algebraic codebook vector, array of type Word16
350      pOverflow, Flag set when overflow occurs, pointer of type Flag *
351  
352   Returns:
353      None
354  
355   Global Variables Used:
356      None
357  
358   Local Variables Needed:
359      None
360  
361  ------------------------------------------------------------------------------
362   FUNCTION DESCRIPTION
363  
364   Search the best codevector; determine positions of the 2 pulses
365   in the 40-sample frame.
366  
367  ------------------------------------------------------------------------------
368   REQUIREMENTS
369  
370   None
371  
372  ------------------------------------------------------------------------------
373   REFERENCES
374  
375   c2_11pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
376  
377  ------------------------------------------------------------------------------
378   PSEUDO-CODE
379  
380  
381  ------------------------------------------------------------------------------
382   RESOURCES USED [optional]
383  
384   When the code is written for a specific target processor the
385   the resources used should be documented below.
386  
387   HEAP MEMORY USED: x bytes
388  
389   STACK MEMORY USED: x bytes
390  
391   CLOCK CYCLES: (cycle count equation for this function) + (variable
392                  used to represent cycle count for each subroutine
393                  called)
394       where: (cycle count variable) = cycle count for [subroutine
395                                       name]
396  
397  ------------------------------------------------------------------------------
398   CAUTION [optional]
399   [State any special notes, constraints or cautions for users of this function]
400  
401  ------------------------------------------------------------------------------
402  */
403  
search_2i40(Word16 dn[],Word16 rr[][L_CODE],Word16 codvec[],Flag * pOverflow)404  static void search_2i40(
405      Word16 dn[],         /* i : correlation between target and h[] */
406      Word16 rr[][L_CODE], /* i : matrix of autocorrelation          */
407      Word16 codvec[],     /* o : algebraic codebook vector          */
408      Flag   * pOverflow   /* o : Flag set when overflow occurs      */
409  )
410  {
411      Word16 i0;
412      Word16 i1;
413      Word16 ix = 0; /* initialization only needed to keep gcc silent */
414      Word16 track1;
415      Word16 track2;
416      Word16 ipos[NB_PULSE];
417  
418      Word16 psk;
419      Word16 ps0;
420      Word16 ps1;
421      Word16 sq;
422      Word16 sq1;
423  
424      Word16 alpk;
425      Word16 alp;
426      Word16 alp_16;
427  
428      Word32 s;
429      Word32 alp0;
430      Word32 alp1;
431  
432      Word16 i;
433      Word16 *p_codvec = &codvec[0];
434  
435      psk = -1;
436      alpk = 1;
437  
438      for (i = 0; i < NB_PULSE; i++)
439      {
440          *(p_codvec++) = i;
441      }
442  
443      /*------------------------------------------------------------------*
444      * main loop: try 2x4  tracks.                                      *
445      *------------------------------------------------------------------*/
446  
447      for (track1 = 0; track1 < 2; track1++)
448      {
449          for (track2 = 0; track2 < 4; track2++)
450          {
451              /* fix starting position */
452              ipos[0] = startPos1[track1];
453              ipos[1] = startPos2[track2];
454  
455              /*----------------------------------------------------------------*
456              * i0 loop: try 8 positions.                                      *
457              *----------------------------------------------------------------*/
458              for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP)
459              {
460                  ps0 = dn[i0];
461  
462                  /* alp0 = L_mult(rr[i0][i0], _1_4, pOverflow); */
463                  alp0 = (Word32) rr[i0][i0] << 14;
464  
465                  /*-------------------------------------------------------------*
466                  * i1 loop: 8 positions.                                       *
467                  *-------------------------------------------------------------*/
468  
469                  sq = -1;
470                  alp = 1;
471                  ix = ipos[1];
472  
473                  /*---------------------------------------------------------------*
474                  * These index have low complexity address computation because   *
475                  * they are, in fact, pointers with fixed increment. For example,*
476                  * "rr[i0][i2]" is a pointer initialized to "&rr[i0][ipos[2]]"   *
477                  * and incremented by "STEP".                                    *
478                  *---------------------------------------------------------------*/
479  
480                  for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP)
481                  {
482                      /* idx increment = STEP */
483                      ps1 = add(ps0, dn[i1], pOverflow);
484  
485                      /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */
486  
487                      /* idx incr = STEP */
488                      /* alp1 = L_mac(alp0, rr[i1][i1], _1_4, pOverflow); */
489                      alp1 = alp0 + ((Word32) rr[i1][i1] << 14);
490  
491                      /* idx incr = STEP */
492                      /* alp1 = L_mac(alp1, rr[i0][i1], _1_2, pOverflow); */
493                      alp1 += (Word32) rr[i0][i1] << 15;
494  
495                      /* sq1 = mult(ps1, ps1, pOverflow); */
496                      sq1 = (Word16)(((Word32) ps1 * ps1) >> 15);
497  
498                      /* alp_16 = pv_round(alp1, pOverflow); */
499                      alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16);
500  
501                      /* s = L_mult(alp, sq1, pOverflow); */
502                      s = ((Word32) alp * sq1) << 1;
503  
504                      /* s =L_msu(s, sq, alp_16, pOverflow); */
505                      s -= (((Word32) sq * alp_16) << 1);
506  
507                      if (s > 0)
508                      {
509                          sq = sq1;
510                          alp = alp_16;
511                          ix = i1;
512                      }
513  
514                  } /* for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP) */
515  
516                  /* memorize codevector if this one is better than the last one. */
517  
518                  /* s = L_mult(alpk, sq, pOverflow); */
519                  s = ((Word32) alpk * sq) << 1;
520  
521                  /* s = L_msu(s, psk, alp, pOverflow); */
522                  s -= (((Word32) psk * alp) << 1);
523  
524                  if (s > 0)
525                  {
526                      psk = sq;
527                      alpk = alp;
528                      p_codvec = &codvec[0];
529  
530                      *(p_codvec++) = i0;
531                      *(p_codvec) = ix;
532                  }
533  
534              } /* for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP) */
535  
536          } /* for (track2 = 0; track2 < 4; track2++) */
537  
538      } /* for (track1 = 0; track1 < 2; track1++) */
539  
540      return;
541  
542  } /* search_2i40 */
543  
544  /****************************************************************************/
545  
546  
547  /*
548  ------------------------------------------------------------------------------
549   FUNCTION NAME: build_code
550  ------------------------------------------------------------------------------
551   INPUT AND OUTPUT DEFINITIONS
552  
553   Inputs:
554      codvec,  position of pulses, array of type Word16
555      dn_sign, sign of pulses, array of type Word16
556      h,       impulse response of weighted synthesis filter, Word16 array
557  
558   Outputs:
559  
560      cod,       innovative code vector, array of type Word16
561      y[],       filtered innovative code, array of type Word16
562      sign[],    sign of 2 pulses, array of type Word16
563      pOverflow, Flag set when overflow occurs, pointer of type Flag *
564  
565   Returns:
566  
567   Global Variables Used:
568      None
569  
570   Local Variables Needed:
571      None
572  
573  ------------------------------------------------------------------------------
574   FUNCTION DESCRIPTION
575  
576   Builds the codeword, the filtered codeword and index of the
577   codevector, based on the signs and positions of 2 pulses.
578  
579  ------------------------------------------------------------------------------
580   REQUIREMENTS
581  
582   None
583  
584  ------------------------------------------------------------------------------
585   REFERENCES
586  
587   c2_11pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
588  
589  ------------------------------------------------------------------------------
590   PSEUDO-CODE
591  
592  ------------------------------------------------------------------------------
593   RESOURCES USED [optional]
594  
595   When the code is written for a specific target processor the
596   the resources used should be documented below.
597  
598   HEAP MEMORY USED: x bytes
599  
600   STACK MEMORY USED: x bytes
601  
602   CLOCK CYCLES: (cycle count equation for this function) + (variable
603                  used to represent cycle count for each subroutine
604                  called)
605       where: (cycle count variable) = cycle count for [subroutine
606                                       name]
607  
608  ------------------------------------------------------------------------------
609   CAUTION [optional]
610   [State any special notes, constraints or cautions for users of this function]
611  
612  ------------------------------------------------------------------------------
613  */
build_code(Word16 codvec[],Word16 dn_sign[],Word16 cod[],Word16 h[],Word16 y[],Word16 sign[],Flag * pOverflow)614  static Word16 build_code(
615      Word16 codvec[],    /* i : position of pulses                            */
616      Word16 dn_sign[],   /* i : sign of pulses                                */
617      Word16 cod[],       /* o : innovative code vector                        */
618      Word16 h[],         /* i : impulse response of weighted synthesis filter */
619      Word16 y[],         /* o : filtered innovative code                      */
620      Word16 sign[],      /* o : sign of 2 pulses                              */
621      Flag   * pOverflow  /* o : Flag set when overflow occurs                 */
622  )
623  {
624      Word16 i;
625      Word16 j;
626      Word16 k;
627      Word16 track;
628      Word16 index;
629      Word16 _sign[NB_PULSE];
630      Word16 indx;
631      Word16 rsign;
632      Word16 tempWord;
633  
634      Word16 *p0;
635      Word16 *p1;
636  
637      Word32 s;
638  
639      for (i = 0; i < L_CODE; i++)
640      {
641          cod[i] = 0;
642      }
643  
644      indx = 0;
645      rsign = 0;
646  
647      for (k = 0; k < NB_PULSE; k++)
648      {
649          i = codvec[k];      /* read pulse position */
650          j = dn_sign[i];     /* read sign           */
651  
652          /* index = pos/5 */
653          /* index = mult(i, 6554, pOverflow); */
654          index = (Word16)(((Word32) i * 6554) >> 15);
655  
656          /* track = pos%5 */
657          /* tempWord =
658              L_mult(
659              index,
660              5,
661              pOverflow); */
662          tempWord = ((Word32) index * 5) << 1;
663  
664          /* tempWord =
665              L_shr(
666              tempWord,
667              1,
668              pOverflow); */
669          tempWord >>= 1;
670  
671  
672          /* track =
673              sub(
674              i,
675              tempWord,
676              pOverflow); */
677          track = i - tempWord;
678  
679          tempWord = track;
680  
681          if (tempWord == 0)
682          {
683              track = 1;
684  
685              /* index =
686                  shl(
687                  index,
688                  6,
689                  pOverflow); */
690              index <<= 6;
691          }
692          else if (track == 1)
693          {
694              tempWord = k;
695  
696              if (tempWord == 0)
697              {
698                  track = 0;
699                  /* index =
700                      shl(
701                      index,
702                      1,
703                      pOverflow); */
704                  index <<= 1;
705              }
706              else
707              {
708                  track = 1;
709  
710                  /* tempWord =
711                      shl(
712                      index,
713                      6,
714                      pOverflow); */
715                  tempWord = index << 6;
716  
717                  /* index =
718                      add(
719                      tempWord,
720                      16,
721                      pOverflow); */
722                  index = tempWord + 16;
723              }
724          }
725          else if (track == 2)
726          {
727              track = 1;
728  
729              /* tempWord =
730                  shl(
731                  index,
732                  6,
733                  pOverflow); */
734              tempWord = index << 6;
735  
736              /* index =
737                  add(
738                  tempWord,
739                  32,
740                  pOverflow); */
741              index = tempWord + 32;
742          }
743          else if (track == 3)
744          {
745              track = 0;
746  
747              /* tempWord =
748                  shl(
749                  index,
750                  1,
751                  pOverflow); */
752              tempWord = index << 1;
753  
754              /* index =
755                  add(
756                  tempWord,
757                  1,
758                  pOverflow); */
759              index = tempWord + 1;
760          }
761          else if (track == 4)
762          {
763              track = 1;
764  
765              /* tempWord =
766                  shl(
767                  index,
768                  6,
769                  pOverflow); */
770              tempWord = index << 6;
771  
772              /* index =
773                  add(
774                  tempWord,
775                  48,
776                  pOverflow); */
777              index = tempWord + 48;
778          }
779  
780          if (j > 0)
781          {
782              cod[i] = 8191;
783              _sign[k] = 32767;
784  
785              tempWord =
786                  shl(
787                      1,
788                      track,
789                      pOverflow);
790  
791              rsign =
792                  add(
793                      rsign,
794                      tempWord,
795                      pOverflow);
796          }
797          else
798          {
799              cod[i] = -8192;
800              _sign[k] = (Word16) - 32768L;
801          }
802  
803          indx =
804              add(
805                  indx,
806                  index,
807                  pOverflow);
808      }
809      *sign = rsign;
810  
811      p0 = h - codvec[0];
812      p1 = h - codvec[1];
813  
814      for (i = 0; i < L_CODE; i++)
815      {
816          s = 0;
817  
818          s =
819              L_mac(
820                  s,
821                  *p0++,
822                  _sign[0],
823                  pOverflow);
824  
825          s =
826              L_mac(
827                  s,
828                  *p1++,
829                  _sign[1],
830                  pOverflow);
831  
832          y[i] =
833              pv_round(
834                  s,
835                  pOverflow);
836      }
837  
838      return indx;
839  }
840  
841  
842