1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23 Available from http://www.3gpp.org
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 ****************************************************************************************/
30 ------------------------------------------------------------------------------
36 ------------------------------------------------------------------------------
39 Purpose : Searches a 17 bit algebraic codebook containing 4 pulses
40 in a frame of 40 samples
41 ------------------------------------------------------------------------------
44 /*----------------------------------------------------------------------------
46 ----------------------------------------------------------------------------*/
55 /*--------------------------------------------------------------------------*/
61 /*----------------------------------------------------------------------------
63 ; Define module specific macros here
64 ----------------------------------------------------------------------------*/
66 /*----------------------------------------------------------------------------
68 ; Include all pre-processor statements here. Include conditional
69 ; compile variables also.
70 ----------------------------------------------------------------------------*/
73 /*----------------------------------------------------------------------------
74 ; LOCAL FUNCTION DEFINITIONS
75 ; Function Prototype declaration
76 ----------------------------------------------------------------------------*/
78 static void search_4i40(
79 Word16 dn[], /* i : correlation between target and h[] */
80 Word16 dn2[], /* i : maximum of corr. in each track. */
81 Word16 rr[][L_CODE],/* i : matrix of autocorrelation */
82 Word16 codvec[], /* o : algebraic codebook vector */
83 Flag * pOverflow /* o : Flag set when overflow occurs */
86 static Word16 build_code(
87 Word16 codvec[], /* i : algebraic codebook vector */
88 Word16 dn_sign[], /* i : sign of dn[] */
89 Word16 cod[], /* o : algebraic (fixed) codebook excitation */
90 Word16 h[], /* i : impulse response of weighted synthesis filter */
91 Word16 y[], /* o : filtered fixed codebook excitation */
92 Word16 sign[], /* o : index of 4 pulses (position+sign+ampl)*4 */
93 const Word16* gray_ptr, /* i : ptr to read-only table */
94 Flag * pOverflow /* o : Flag set when overflow occurs */
97 /*----------------------------------------------------------------------------
98 ; LOCAL VARIABLE DEFINITIONS
99 ; Variable declaration - defined here and used outside this module
100 ----------------------------------------------------------------------------*/
102 /*----------------------------------------------------------------------------
103 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
104 ; Declare variables used in this module but defined elsewhere
105 ----------------------------------------------------------------------------*/
108 ------------------------------------------------------------------------------
109 FUNCTION NAME: code_4i40_17bits()
110 ------------------------------------------------------------------------------
111 INPUT AND OUTPUT DEFINITIONS
114 x[] Array of type Word16 -- target vector
115 h[] Array of type Word16 -- impulse response of weighted synthesis filter
116 h[-L_subfr..-1] must be set to zero.
118 T0 Array of type Word16 -- Pitch lag
119 pitch_sharp, Array of type Word16 -- Last quantized pitch gain
122 code[] Array of type Word16 -- Innovative codebook
123 y[] Array of type Word16 -- filtered fixed codebook excitation
124 * sign Pointer of type Word16 -- Pointer to the signs of 4 pulses
125 pOverflow Pointer to Flag -- set when overflow occurs
130 Global Variables Used:
133 Local Variables Needed:
135 ------------------------------------------------------------------------------
138 PURPOSE: Searches a 17 bit algebraic codebook containing 4 pulses
139 in a frame of 40 samples.
142 The code length is 40, containing 4 nonzero pulses: i0...i3.
143 All pulses can have two possible amplitudes: +1 or -1.
144 Pulse i0 to i2 can have 8 possible positions, pulse i3 can have
147 i0 : 0, 5, 10, 15, 20, 25, 30, 35.
148 i1 : 1, 6, 11, 16, 21, 26, 31, 36.
149 i2 : 2, 7, 12, 17, 22, 27, 32, 37.
150 i3 : 3, 8, 13, 18, 23, 28, 33, 38.
151 4, 9, 14, 19, 24, 29, 34, 39.
153 ------------------------------------------------------------------------------
158 ------------------------------------------------------------------------------
161 [1] c3_14pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
163 ------------------------------------------------------------------------------
166 ------------------------------------------------------------------------------
168 [State any special notes, constraints or cautions for users of this function]
170 ------------------------------------------------------------------------------
173 Word16 code_4i40_17bits(
174 Word16 x[], /* i : target vector */
175 Word16 h[], /* i : impulse response of weighted synthesis filter */
176 /* h[-L_subfr..-1] must be set to zero. */
177 Word16 T0, /* i : Pitch lag */
178 Word16 pitch_sharp, /* i : Last quantized pitch gain */
179 Word16 code[], /* o : Innovative codebook */
180 Word16 y[], /* o : filtered fixed codebook excitation */
181 Word16 * sign, /* o : Signs of 4 pulses */
182 const Word16* gray_ptr, /* i : ptr to read-only table */
183 Flag * pOverflow /* o : Flag set when overflow occurs */
186 Word16 codvec[NB_PULSE];
189 Word16 dn_sign[L_CODE];
191 Word16 rr[L_CODE][L_CODE];
197 sharp = pitch_sharp << 1;
201 for (i = T0; i < L_CODE; i++)
243 /* function result */
255 /*-----------------------------------------------------------------*
256 * Compute innovation vector gain. *
257 * Include fixed-gain pitch contribution into code[]. *
258 *-----------------------------------------------------------------*/
260 tempWord = T0 - L_CODE;
264 for (i = T0; i < L_CODE; i++)
282 /****************************************************************************/
285 ------------------------------------------------------------------------------
286 FUNCTION NAME: search_4i40()
287 ------------------------------------------------------------------------------
288 INPUT AND OUTPUT DEFINITIONS
291 dn[] Array of type Word16 -- correlation between target and h[]
292 dn2[] Array of type Word16 -- maximum of corr. in each track.
293 rr[][L_CODE] Double Array of type Word16 -- autocorrelation matrix
296 codvec[] Array of type Word16 -- algebraic codebook vector
297 pOverflow Pointer to Flag -- set when overflow occurs
302 Global Variables Used:
305 Local Variables Needed:
308 ------------------------------------------------------------------------------
311 PURPOSE: Search the best codevector; determine positions of the 4 pulses
312 in the 40-sample frame.
314 ------------------------------------------------------------------------------
319 ------------------------------------------------------------------------------
322 [1] c4_17pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
324 ------------------------------------------------------------------------------
327 ------------------------------------------------------------------------------
329 [State any special notes, constraints or cautions for users of this function]
331 ------------------------------------------------------------------------------
333 static void search_4i40(
334 Word16 dn[], /* i : correlation between target and h[] */
335 Word16 dn2[], /* i : maximum of corr. in each track. */
336 Word16 rr[][L_CODE], /* i : matrix of autocorrelation */
337 Word16 codvec[], /* o : algebraic codebook vector */
338 Flag * pOverflow /* o : Flag set when overflow occurs */
346 Word16 ix = 0; /* initialization only needed to keep gcc silent */
347 Word16 ps = 0; /* initialization only needed to keep gcc silent */
352 Word16 ipos[NB_PULSE];
363 Word16 *p_codvec = &codvec[0];
369 OSCL_UNUSED_ARG(pOverflow);
374 for (i = 0; i < NB_PULSE; i++)
379 for (track = 3; track < 5; track++)
381 /* fix starting position */
388 /*------------------------------------------------------------------*
389 * main loop: try 4 tracks. *
390 *------------------------------------------------------------------*/
392 for (i = 0; i < NB_PULSE; i++)
394 /*----------------------------------------------------------------*
395 * i0 loop: try 4 positions (use position with max of corr.). *
396 *----------------------------------------------------------------*/
398 for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP)
404 alp0 = (Word32) rr[i0][i0] << 14;
406 /*----------------------------------------------------------------*
407 * i1 loop: 8 positions. *
408 *----------------------------------------------------------------*/
415 /* initialize 4 index for next loop. */
416 /*-------------------------------------------------------------------*
417 * These index have low complexity address computation because *
418 * they are, in fact, pointers with fixed increment. For example, *
419 * "rr[i0][i3]" is a pointer initialized to "&rr[i0][ipos[3]]" *
420 * and incremented by "STEP". *
421 *-------------------------------------------------------------------*/
423 for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP)
425 /* idx increment = STEP */
426 /* ps1 = add(ps0, dn[i1], pOverflow); */
429 /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */
431 /* alp1 = L_mac(alp0, rr[i1][i1], _1_4, pOverflow); */
432 alp1 = alp0 + ((Word32) rr[i1][i1] << 14);
434 /* alp1 = L_mac(alp1, rr[i0][i1], _1_2, pOverflow); */
435 alp1 += (Word32) rr[i0][i1] << 15;
437 /* sq1 = mult(ps1, ps1, pOverflow); */
438 sq1 = (Word16)(((Word32) ps1 * ps1) >> 15);
440 /* alp_16 = pv_round(alp1, pOverflow); */
441 alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16);
443 /* s = L_mult(alp, sq1, pOverflow); */
444 s = ((Word32) alp * sq1) << 1;
446 /* s = L_msu(s, sq, alp_16, pOverflow); */
447 s -= (((Word32) sq * alp_16) << 1);
459 /*----------------------------------------------------------------*
460 * i2 loop: 8 positions. *
461 *----------------------------------------------------------------*/
465 /* alp0 = L_mult(alp, _1_4, pOverflow); */
466 alp0 = (Word32) alp << 14;
473 /* initialize 4 index for next loop (see i1 loop) */
475 for (i2 = ipos[2]; i2 < L_CODE; i2 += STEP)
477 /* index increment = STEP */
478 /* ps1 = add(ps0, dn[i2], pOverflow); */
481 /* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */
483 /* idx incr = STEP */
484 /* alp1 = L_mac(alp0, rr[i2][i2], _1_16, pOverflow); */
485 alp1 = alp0 + ((Word32) rr[i2][i2] << 12);
487 /* idx incr = STEP */
488 /* alp1 = L_mac(alp1, rr[i1][i2], _1_8, pOverflow); */
489 alp1 += (Word32) rr[i1][i2] << 13;
491 /* idx incr = STEP */
492 /* alp1 = L_mac(alp1,rr[i0][i2], _1_8, pOverflow); */
493 alp1 += (Word32) rr[i0][i2] << 13;
495 /* sq1 = mult(ps1, ps1, pOverflow); */
496 sq1 = (Word16)(((Word32) ps1 * ps1) >> 15);
498 /* alp_16 = pv_round(alp1, pOverflow); */
499 alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16);
501 /* s = L_mult(alp, sq1, pOverflow); */
502 s = ((Word32) alp * sq1) << 1;
504 /* s = L_msu(s, sq, alp_16, pOverflow); */
505 s -= (((Word32) sq * alp_16) << 1);
517 /*----------------------------------------------------------------*
518 * i3 loop: 8 positions. *
519 *----------------------------------------------------------------*/
522 alp0 = ((Word32)alp << 16);
529 /* initialize 5 index for next loop (see i1 loop) */
531 for (i3 = ipos[3]; i3 < L_CODE; i3 += STEP)
533 /* ps1 = add(ps0, dn[i3], pOverflow); */
534 ps1 = ps0 + dn[i3]; /* index increment = STEP */
536 /* alp1 = alp0 + rr[i0][i3] + rr[i1][i3] + rr[i2][i3] + 1/2*rr[i3][i3]; */
538 /* alp1 = L_mac(alp0, rr[i3][i3], _1_16, pOverflow); */
539 alp1 = alp0 + ((Word32) rr[i3][i3] << 12); /* idx incr = STEP */
541 /* alp1 = L_mac(alp1, rr[i2][i3], _1_8, pOverflow); */
542 alp1 += (Word32) rr[i2][i3] << 13; /* idx incr = STEP */
544 /* alp1 = L_mac(alp1, rr[i1][i3], _1_8, pOverflow); */
545 alp1 += (Word32) rr[i1][i3] << 13; /* idx incr = STEP */
547 /* alp1 = L_mac(alp1, rr[i0][i3], _1_8, pOverflow); */
548 alp1 += (Word32) rr[i0][i3] << 13; /* idx incr = STEP */
550 /* sq1 = mult(ps1, ps1, pOverflow); */
551 sq1 = (Word16)(((Word32) ps1 * ps1) >> 15);
553 /* alp_16 = pv_round(alp1, pOverflow); */
554 alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16);
556 /* s = L_mult(alp, sq1, pOverflow); */
557 s = ((Word32) alp * sq1) << 1;
559 /* s = L_msu(s, sq, alp_16, pOverflow); */
560 s -= (((Word32) sq * alp_16) << 1);
572 /*----------------------------------------------------------------*
573 * memorise codevector if this one is better than the last one. *
574 *----------------------------------------------------------------*/
576 /* s = L_mult(alpk, sq, pOverflow); */
577 s = ((Word32) alpk * sq) << 1;
579 /* s = L_msu(s, psk, alp, pOverflow); */
580 s -= (((Word32) psk * alp) << 1);
586 p_codvec = &codvec[0];
596 /*----------------------------------------------------------------*
597 * Cyclic permutation of i0,i1,i2 and i3. *
598 *----------------------------------------------------------------*/
614 /****************************************************************************/
617 ------------------------------------------------------------------------------
618 FUNCTION NAME: build_code()
619 ------------------------------------------------------------------------------
620 INPUT AND OUTPUT DEFINITIONS
623 codvec[] Array of type Word16 -- position of pulses
624 dn_sign[] Array of type Word16 -- sign of pulses
625 h[] Array of type Word16 -- impulse response of
626 weighted synthesis filter
629 cod[] Array of type Word16 -- innovative code vector
630 y[] Array of type Word16 -- filtered innovative code
631 sign[] Array of type Word16 -- index of 4 pulses (sign + position)
632 pOverflow Pointer to Flag -- set when overflow occurs
637 Global Variables Used:
640 Local Variables Needed:
642 ------------------------------------------------------------------------------
645 PURPOSE: Builds the codeword, the filtered codeword and index of the
646 codevector, based on the signs and positions of 4 pulses.
648 ------------------------------------------------------------------------------
653 ------------------------------------------------------------------------------
656 [1] c4_17pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
658 ------------------------------------------------------------------------------
661 ------------------------------------------------------------------------------
663 [State any special notes, constraints or cautions for users of this function]
665 ------------------------------------------------------------------------------
670 Word16 codvec[], /* i : position of pulses */
671 Word16 dn_sign[], /* i : sign of pulses */
672 Word16 cod[], /* o : innovative code vector */
673 Word16 h[], /* i : impulse response of weighted synthesis filter */
674 Word16 y[], /* o : filtered innovative code */
675 Word16 sign[], /* o : index of 4 pulses (sign+position) */
676 const Word16* gray_ptr, /* i : ptr to read-only table */
677 Flag * pOverflow /* o : Flag set when overflow occurs */
685 Word16 _sign[NB_PULSE];
693 Word16 *p_cod = &cod[0];
697 for (i = 0; i < L_CODE; i++)
705 for (k = 0; k < NB_PULSE; k++)
707 i = codvec[k]; /* read pulse position */
708 j = dn_sign[i]; /* read sign */
711 /* index = mult(i, 6554, pOverflow); */
712 index = (Word16)(((Word32) i * 6554) >> 15);
715 /* s = L_mult(index, 5, pOverflow); */
716 s = ((Word32) index * 5) << 1;
718 /* s = L_shr(s, 1, pOverflow); */
721 /* track = sub(i, (Word16) s, pOverflow); */
722 track = i - (Word16) s;
724 index = gray_ptr[index];
728 /* index = shl(index, 3, pOverflow); */
733 /* index = shl(index, 6, pOverflow); */
738 /* index = shl(index, 10, pOverflow); */
745 /* index = shl(index, 10, pOverflow); */
748 /* index = add(index, 512, pOverflow); */
757 /* track = shl(1, track, pOverflow); */
760 /* rsign = add(rsign, track, pOverflow); */
766 _sign[k] = (Word16) - 32768L;
769 /* indx = add(indx, index, pOverflow); */
779 for (i = 0; i < L_CODE; i++)
815 } /* for (i = 0; i < L_CODE; i++) */