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 ------------------------------------------------------------------------------
42 /*----------------------------------------------------------------------------
44 ----------------------------------------------------------------------------*/
53 /*----------------------------------------------------------------------------
55 ; Define module specific macros here
56 ----------------------------------------------------------------------------*/
58 /*----------------------------------------------------------------------------
60 ; Include all pre-processor statements here. Include conditional
61 ; compile variables also.
62 ----------------------------------------------------------------------------*/
66 /*----------------------------------------------------------------------------
67 ; LOCAL FUNCTION DEFINITIONS
68 ; Function Prototype declaration
69 ----------------------------------------------------------------------------*/
70 static void search_3i40(
71 Word16 dn[], /* i : correlation between target and h[] */
72 Word16 dn2[], /* i : maximum of corr. in each track. */
73 Word16 rr[][L_CODE],/* i : matrix of autocorrelation */
74 Word16 codvec[], /* o : algebraic codebook vector */
75 Flag * pOverflow /* o : Flag set when overflow occurs */
78 static Word16 build_code(
79 Word16 codvec[], /* i : algebraic codebook vector */
80 Word16 dn_sign[], /* i : sign of dn[] */
81 Word16 cod[], /* o : algebraic (fixed) codebook excitation */
82 Word16 h[], /* i : impulse response of weighted synthesis filter */
83 Word16 y[], /* o : filtered fixed codebook excitation */
84 Word16 sign[], /* o : sign of 3 pulses */
85 Flag * pOverflow /* o : Flag set when overflow occurs */
88 /*----------------------------------------------------------------------------
89 ; LOCAL VARIABLE DEFINITIONS
90 ; Variable declaration - defined here and used outside this module
91 ----------------------------------------------------------------------------*/
93 /*----------------------------------------------------------------------------
94 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
95 ; Declare variables used in this module but defined elsewhere
96 ----------------------------------------------------------------------------*/
99 ------------------------------------------------------------------------------
100 FUNCTION NAME: code_3i40_14bits
101 ------------------------------------------------------------------------------
102 INPUT AND OUTPUT DEFINITIONS
105 x[] Array of type Word16 -- target vector
106 h[] Array of type Word16 -- impulse response of weighted synthesis filter
107 h[-L_subfr..-1] must be set to zero.
109 T0 Array of type Word16 -- Pitch lag
110 pitch_sharp, Array of type Word16 -- Last quantized pitch gain
113 code[] Array of type Word16 -- Innovative codebook
114 y[] Array of type Word16 -- filtered fixed codebook excitation
115 * sign Pointer of type Word16 -- Pointer to the signs of 3 pulses
116 pOverflow Pointer to Flag -- set when overflow occurs
121 Global Variables Used:
124 Local Variables Needed:
127 ------------------------------------------------------------------------------
130 PURPOSE: Searches a 14 bit algebraic codebook containing 3 pulses
131 in a frame of 40 samples.
134 The code length is 40, containing 3 nonzero pulses: i0...i2.
135 All pulses can have two possible amplitudes: +1 or -1.
136 Pulse i0 can have 8 possible positions, pulses i1 and i2 can have
139 i0 : 0, 5, 10, 15, 20, 25, 30, 35.
140 i1 : 1, 6, 11, 16, 21, 26, 31, 36.
141 3, 8, 13, 18, 23, 28, 33, 38.
142 i2 : 2, 7, 12, 17, 22, 27, 32, 37.
143 4, 9, 14, 19, 24, 29, 34, 39.
145 ------------------------------------------------------------------------------
150 ------------------------------------------------------------------------------
153 [1] c3_14pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
155 ------------------------------------------------------------------------------
158 ------------------------------------------------------------------------------
160 [State any special notes, constraints or cautions for users of this function]
162 ------------------------------------------------------------------------------
165 Word16 code_3i40_14bits(
166 Word16 x[], /* i : target vector */
167 Word16 h[], /* i : impulse response of weighted synthesis filter */
168 /* h[-L_subfr..-1] must be set to zero. */
169 Word16 T0, /* i : Pitch lag */
170 Word16 pitch_sharp, /* i : Last quantized pitch gain */
171 Word16 code[], /* o : Innovative codebook */
172 Word16 y[], /* o : filtered fixed codebook excitation */
173 Word16 * sign, /* o : Signs of 3 pulses */
174 Flag * pOverflow /* o : Flag set when overflow occurs */
177 Word16 codvec[NB_PULSE];
180 Word16 dn_sign[L_CODE];
181 Word16 rr[L_CODE][L_CODE];
187 /* sharp = shl(pitch_sharp, 1, pOverflow); */
188 sharp = pitch_sharp << 1;
192 for (i = T0; i < L_CODE; i++)
234 /* function result */
245 /*-----------------------------------------------------------------*
246 * Compute innovation vector gain. *
247 * Include fixed-gain pitch contribution into code[]. *
248 *-----------------------------------------------------------------*/
252 for (i = T0; i < L_CODE; i++)
270 /****************************************************************************/
273 ------------------------------------------------------------------------------
274 FUNCTION NAME: search_3i40
275 ------------------------------------------------------------------------------
276 INPUT AND OUTPUT DEFINITIONS
279 dn[] Array of type Word16 -- correlation between target and h[]
280 dn2[] Array of type Word16 -- maximum of corr. in each track.
281 rr[][L_CODE] Double Array of type Word16 -- autocorrelation matrix
284 codvec[] Array of type Word16 -- algebraic codebook vector
285 pOverflow Pointer to Flag -- set when overflow occurs
290 Global Variables Used:
293 Local Variables Needed:
296 ------------------------------------------------------------------------------
299 PURPOSE: Search the best codevector; determine positions of the 3 pulses
300 in the 40-sample frame.
301 ------------------------------------------------------------------------------
306 ------------------------------------------------------------------------------
309 [1] c3_14pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
311 ------------------------------------------------------------------------------
314 ------------------------------------------------------------------------------
316 [State any special notes, constraints or cautions for users of this function]
318 ------------------------------------------------------------------------------
320 static void search_3i40(
321 Word16 dn[], /* i : correlation between target and h[] */
322 Word16 dn2[], /* i : maximum of corr. in each track. */
323 Word16 rr[][L_CODE], /* i : matrix of autocorrelation */
324 Word16 codvec[], /* o : algebraic codebook vector */
325 Flag * pOverflow /* o : Flag set when overflow occurs */
332 Word16 ix = 0; /* initialization only needed to keep gcc silent */
333 Word16 ps = 0; /* initialization only needed to keep gcc silent */
339 Word16 ipos[NB_PULSE];
350 Word16 *p_codvec = &codvec[0];
359 for (i = 0; i < NB_PULSE; i++)
364 for (track1 = 1; track1 < 4; track1 += 2)
366 for (track2 = 2; track2 < 5; track2 += 2)
368 /* fix starting position */
374 /*------------------------------------------------------------------*
375 * main loop: try 3 tracks. *
376 *------------------------------------------------------------------*/
378 for (i = 0; i < NB_PULSE; i++)
380 /*----------------------------------------------------------------*
381 * i0 loop: try 8 positions. *
382 *----------------------------------------------------------------*/
384 /* account for ptr. init. (rr[io]) */
385 for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP)
391 /* alp0 = L_mult(rr[i0][i0],_1_4, pOverflow); */
392 alp0 = (Word32) rr[i0][i0] << 14;
394 /*----------------------------------------------------------------*
395 * i1 loop: 8 positions. *
396 *----------------------------------------------------------------*/
403 /* initialize 4 index for next loop. */
404 /*-------------------------------------------------------------------*
405 * These index have low complexity address computation because *
406 * they are, in fact, pointers with fixed increment. For example, *
407 * "rr[i0][i2]" is a pointer initialized to "&rr[i0][ipos[2]]" *
408 * and incremented by "STEP". *
409 *-------------------------------------------------------------------*/
411 for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP)
413 /* idx increment = STEP */
414 /* ps1 = add(ps0, dn[i1], pOverflow); */
417 /* alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1]; */
419 /* idx incr = STEP */
420 /* alp1 = L_mac(alp0, rr[i1][i1], _1_4, pOverflow); */
421 alp1 = alp0 + ((Word32) rr[i1][i1] << 14);
423 /* idx incr = STEP */
424 /* alp1 = L_mac(alp1, rr[i0][i1], _1_2, pOverflow); */
425 alp1 += (Word32) rr[i0][i1] << 15;
427 /* sq1 = mult(ps1, ps1, pOverflow); */
428 sq1 = (Word16)(((Word32) ps1 * ps1) >> 15);
430 /* alp_16 = pv_round(alp1, pOverflow); */
431 alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16);
433 /* s = L_mult(alp, sq1, pOverflow); */
434 s = ((Word32) alp * sq1) << 1;
436 /* s = L_msu(s, sq, alp_16, pOverflow); */
437 s -= (((Word32) sq * alp_16) << 1);
449 /*----------------------------------------------------------------*
450 * i2 loop: 8 positions. *
451 *----------------------------------------------------------------*/
455 /* alp0 = L_mult(alp, _1_4, pOverflow); */
456 alp0 = (Word32) alp << 14;
463 /* initialize 4 index for next loop (see i1 loop) */
465 for (i2 = ipos[2]; i2 < L_CODE; i2 += STEP)
467 /* index increment = STEP */
468 /* ps1 = add(ps0, dn[i2], pOverflow); */
471 /* alp1 = alp0 + rr[i0][i2] + rr[i1][i2] + 1/2*rr[i2][i2]; */
473 /* idx incr = STEP */
474 /* alp1 = L_mac(alp0, rr[i2][i2], _1_16, pOverflow); */
475 alp1 = alp0 + ((Word32) rr[i2][i2] << 12);
477 /* idx incr = STEP */
478 /* alp1 = L_mac(alp1, rr[i1][i2], _1_8, pOverflow); */
479 alp1 += (Word32) rr[i1][i2] << 13;
481 /* idx incr = STEP */
482 /* alp1 = L_mac(alp1,rr[i0][i2], _1_8, pOverflow); */
483 alp1 += (Word32) rr[i0][i2] << 13;
485 /* sq1 = mult(ps1, ps1, pOverflow); */
486 sq1 = (Word16)(((Word32) ps1 * ps1) >> 15);
488 /* alp_16 = pv_round(alp1, pOverflow); */
489 alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16);
491 /* s = L_mult(alp, sq1, pOverflow); */
492 s = ((Word32) alp * sq1) << 1;
494 /* s = L_msu(s, sq, alp_16, pOverflow); */
495 s -= (((Word32) sq * alp_16) << 1);
507 /* memorize codevector if this one
508 * is better than the last one.
511 s = L_mult(alpk, sq, pOverflow);
512 //s = ((Word32) alpk * sq) << 1;
514 s = L_msu(s, psk, alp, pOverflow);
515 //s -= (((Word32) psk * alp) << 1);
521 p_codvec = &codvec[0];
529 /*----------------------------------------------------------------*
530 * Cyclic permutation of i0, i1 and i2. *
531 *----------------------------------------------------------------*/
543 /****************************************************************************/
546 ------------------------------------------------------------------------------
547 FUNCTION NAME: build_code()
548 ------------------------------------------------------------------------------
549 INPUT AND OUTPUT DEFINITIONS
552 codvec[] Array of type Word16 -- position of pulses
553 dn_sign[] Array of type Word16 -- sign of pulses
554 h[] Array of type Word16 -- impulse response of
555 weighted synthesis filter
558 cod[] Array of type Word16 -- innovative code vector
559 y[] Array of type Word16 -- filtered innovative code
560 sign[] Array of type Word16 -- sign of 3 pulses
561 pOverflow Pointer to Flag -- set when overflow occurs
566 Global Variables Used:
569 Local Variables Needed:
572 ------------------------------------------------------------------------------
575 PURPOSE: Builds the codeword, the filtered codeword and index of the
576 codevector, based on the signs and positions of 3 pulses.
578 ------------------------------------------------------------------------------
583 ------------------------------------------------------------------------------
586 [1] c3_14pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
588 ------------------------------------------------------------------------------
591 ------------------------------------------------------------------------------
593 [State any special notes, constraints or cautions for users of this function]
595 ------------------------------------------------------------------------------
600 Word16 codvec[], /* i : position of pulses */
601 Word16 dn_sign[], /* i : sign of pulses */
602 Word16 cod[], /* o : innovative code vector */
603 Word16 h[], /* i : impulse response of weighted synthesis filter */
604 Word16 y[], /* o : filtered innovative code */
605 Word16 sign[], /* o : sign of 3 pulses */
606 Flag *pOverflow /* o : Flag set when overflow occurs */
614 Word16 _sign[NB_PULSE];
624 for (i = 0; i < L_CODE; i++)
632 for (k = 0; k < NB_PULSE; k++)
634 i = codvec[k]; /* read pulse position */
635 j = dn_sign[i]; /* read sign */
638 /* index = mult(i, 6554, pOverflow); */
639 index = (Word16)(((Word32) i * 6554) >> 15);
642 /* s = L_mult(index, 5, pOverflow); */
643 s = ((Word32) index * 5) << 1;
645 /* s = L_shr(s, 1, pOverflow); */
648 /* track = sub(i, (Word16) s, pOverflow); */
649 track = i - (Word16) s;
653 /* index = shl(index, 4, pOverflow); */
660 /* index = shl(index, 8, pOverflow); */
667 /* index = shl(index, 4, pOverflow); */
670 /* index = add(index, 8, pOverflow); */
677 /* index = shl(index, 8, pOverflow); */
680 /* index = add(index, 128, pOverflow); */
689 /* track = shl(1, track, pOverflow); */
692 /* rsign = add(rsign, track, pOverflow); */
698 _sign[k] = (Word16) - 32768L;
701 /* indx = add(indx, index, pOverflow); */
710 for (i = 0; i < L_CODE; i++)