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/c1035pf.c
35 Functions: q_p
36 build_code
37 code_10i40_35bits
38
39
40 Date: 09/28/2000
41
42 ------------------------------------------------------------------------------
43 REVISION HISTORY
44
45 Description: Updated template. Cleaned up code. Passing in a pointer to
46 overflow flag for build_code() and code_10i40_35bits() functions.
47 Removed unnecessary header files.
48
49 Description:
50 1. Eliminated unused include files.
51 2. Replaced array addressing by pointers
52 3. Eliminated math operations that unnecessary checked for
53 saturation
54 4. Replaced for-loops with memset()
55
56 Description: Changed function name to pv_round to avoid conflict with
57 round function in C standard library.
58
59 Description: Replaced OSCL mem type functions and eliminated include
60 files that now are chosen by OSCL definitions
61
62 Description: Replaced "int" and/or "char" with OSCL defined types.
63
64 Description:
65
66 ------------------------------------------------------------------------------
67 MODULE DESCRIPTION
68
69 This file contains the function that searches a 35 bit algebraic codebook
70 containing 10 pulses in a frame of 40 samples.
71
72 ------------------------------------------------------------------------------
73 */
74
75 /*----------------------------------------------------------------------------
76 ; INCLUDES
77 ----------------------------------------------------------------------------*/
78 #include <string.h>
79
80 #include "c1035pf.h"
81 #include "cnst.h"
82 #include "basic_op.h"
83 #include "inv_sqrt.h"
84 #include "set_sign.h"
85 #include "cor_h.h"
86 #include "cor_h_x.h"
87 #include "s10_8pf.h"
88
89 /*----------------------------------------------------------------------------
90 ; MACROS
91 ; [Define module specific macros here]
92 ----------------------------------------------------------------------------*/
93
94
95 /*----------------------------------------------------------------------------
96 ; DEFINES
97 ; [Include all pre-processor statements here. Include conditional
98 ; compile variables also.]
99 ----------------------------------------------------------------------------*/
100 #define NB_PULSE 10
101
102 /*----------------------------------------------------------------------------
103 ; LOCAL FUNCTION DEFINITIONS
104 ; [List function prototypes here]
105 ----------------------------------------------------------------------------*/
106
107 /*----------------------------------------------------------------------------
108 ; LOCAL VARIABLE DEFINITIONS
109 ; [Variable declaration - defined here and used outside this module]
110 ----------------------------------------------------------------------------*/
111
112 /*
113 ------------------------------------------------------------------------------
114 FUNCTION NAME: q_p
115 ------------------------------------------------------------------------------
116 INPUT AND OUTPUT DEFINITIONS
117
118 Inputs:
119 pShift_reg = pointer to Old CN generator shift register state (Word32)
120 no_bits = Number of bits (Word16)
121
122 Outputs:
123 pShift_reg -> Updated CN generator shift register state
124
125 Returns:
126 noise_bits = Generated random integer value (Word16)
127
128 Global Variables Used:
129 None
130
131 Local Variables Needed:
132 None
133
134 ------------------------------------------------------------------------------
135 FUNCTION DESCRIPTION
136
137 This is a local function that determnes the index of the pulses by looking up
138 the gray encoder table
139
140 ------------------------------------------------------------------------------
141 REQUIREMENTS
142
143 None
144
145 ------------------------------------------------------------------------------
146 REFERENCES
147
148 c1035pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
149
150 ------------------------------------------------------------------------------
151 PSEUDO-CODE
152
153 void q_p (
154 Word16 *ind, // Pulse position
155 Word16 n // Pulse number
156 )
157 {
158 Word16 tmp;
159
160 tmp = *ind;
161
162 if (sub (n, 5) < 0)
163 {
164 *ind = (tmp & 0x8) | gray[tmp & 0x7];
165 }
166 else
167 {
168 *ind = gray[tmp & 0x7];
169 }
170 }
171
172 ------------------------------------------------------------------------------
173 RESOURCES USED [optional]
174
175 When the code is written for a specific target processor the
176 the resources used should be documented below.
177
178 HEAP MEMORY USED: x bytes
179
180 STACK MEMORY USED: x bytes
181
182 CLOCK CYCLES: (cycle count equation for this function) + (variable
183 used to represent cycle count for each subroutine
184 called)
185 where: (cycle count variable) = cycle count for [subroutine
186 name]
187
188 ------------------------------------------------------------------------------
189 CAUTION [optional]
190 [State any special notes, constraints or cautions for users of this function]
191
192 ------------------------------------------------------------------------------
193 */
194
195 /*----------------------------------------------------------------------------
196 ; FUNCTION CODE
197 ----------------------------------------------------------------------------*/
198
q_p(Word16 * pInd,Word16 n)199 void q_p(
200 Word16 *pInd, /* Pulse position */
201 Word16 n /* Pulse number */
202 )
203 {
204 Word16 tmp;
205
206 tmp = *pInd;
207
208 if (n < 5)
209 {
210 *pInd = (tmp & 0x8) | gray[tmp & 0x7];
211 }
212 else
213 {
214 *pInd = gray[tmp & 0x7];
215 }
216 }
217
218 /*
219 ------------------------------------------------------------------------------
220 FUNCTION NAME: build_code
221 ------------------------------------------------------------------------------
222 INPUT AND OUTPUT DEFINITIONS
223
224 Inputs:
225 pSeed = pointer to the Old CN generator shift register state (Word32)
226 n_param = Number of parameters to randomize (Word16)
227 param_size_table = table holding paameter sizes (Word16)
228 param[] = array to hold CN generated paramters (Word16)
229 pOverflow = pointer to overflow flag (Flag)
230
231 Outputs:
232 param[] = CN generated parameters (Word16)
233 pSeed = Updated CN generator shift register state (Word16)
234 pOverflow -> 1 if overflow occured
235
236 Returns:
237 None
238
239 Global Variables Used:
240 None
241
242 Local Variables Needed:
243 None
244
245 ------------------------------------------------------------------------------
246 FUNCTION DESCRIPTION
247
248 This function builds the codeword, the filtered codeword and index of the
249 codevector, based on the signs and positions of 10 pulses.
250 ------------------------------------------------------------------------------
251 REQUIREMENTS
252
253 None
254
255 ------------------------------------------------------------------------------
256 REFERENCES
257
258 c1035pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
259
260 ------------------------------------------------------------------------------
261 PSEUDO-CODE
262 static void build_code (
263 Word16 codvec[], // (i) : position of pulses
264 Word16 sign[], // (i) : sign of d[n]
265 Word16 cod[], // (o) : innovative code vector
266 Word16 h[], // (i) : impulse response of weighted synthesis filter
267 Word16 y[], // (o) : filtered innovative code
268 Word16 indx[] // (o) : index of 10 pulses (sign+position)
269 )
270 {
271 Word16 i, j, k, track, index, _sign[NB_PULSE];
272 Word16 *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9;
273 Word32 s;
274
275 for (i = 0; i < L_CODE; i++)
276 {
277 cod[i] = 0;
278 }
279 for (i = 0; i < NB_TRACK; i++)
280 {
281 indx[i] = -1;
282 }
283
284 for (k = 0; k < NB_PULSE; k++)
285 {
286 // read pulse position
287 i = codvec[k];
288 // read sign
289 j = sign[i];
290
291 index = mult (i, 6554); // index = pos/5
292 // track = pos%5
293 track = sub (i, extract_l (L_shr (L_mult (index, 5), 1)));
294
295 if (j > 0)
296 {
297 cod[i] = add (cod[i], 4096);
298 _sign[k] = 8192;
299
300 }
301 else
302 {
303 cod[i] = sub (cod[i], 4096);
304 _sign[k] = -8192;
305 index = add (index, 8);
306 }
307
308 if (indx[track] < 0)
309 {
310 indx[track] = index;
311 }
312 else
313 {
314 if (((index ^ indx[track]) & 8) == 0)
315 {
316 // sign of 1st pulse == sign of 2nd pulse
317
318 if (sub (indx[track], index) <= 0)
319 {
320 indx[track + 5] = index;
321 }
322 else
323 {
324 indx[track + 5] = indx[track];
325 indx[track] = index;
326 }
327 }
328 else
329 {
330 // sign of 1st pulse != sign of 2nd pulse
331
332 if (sub ((Word16)(indx[track] & 7), (Word16)(index & 7)) <= 0)
333 {
334 indx[track + 5] = indx[track];
335 indx[track] = index;
336 }
337 else
338 {
339 indx[track + 5] = index;
340 }
341 }
342 }
343 }
344
345 p0 = h - codvec[0];
346 p1 = h - codvec[1];
347 p2 = h - codvec[2];
348 p3 = h - codvec[3];
349 p4 = h - codvec[4];
350 p5 = h - codvec[5];
351 p6 = h - codvec[6];
352 p7 = h - codvec[7];
353 p8 = h - codvec[8];
354 p9 = h - codvec[9];
355
356 for (i = 0; i < L_CODE; i++)
357 {
358 s = 0;
359 s = L_mac (s, *p0++, _sign[0]);
360 s = L_mac (s, *p1++, _sign[1]);
361 s = L_mac (s, *p2++, _sign[2]);
362 s = L_mac (s, *p3++, _sign[3]);
363 s = L_mac (s, *p4++, _sign[4]);
364 s = L_mac (s, *p5++, _sign[5]);
365 s = L_mac (s, *p6++, _sign[6]);
366 s = L_mac (s, *p7++, _sign[7]);
367 s = L_mac (s, *p8++, _sign[8]);
368 s = L_mac (s, *p9++, _sign[9]);
369 y[i] = pv_round (s);
370 }
371 }
372
373 ------------------------------------------------------------------------------
374 RESOURCES USED [optional]
375
376 When the code is written for a specific target processor the
377 the resources used should be documented below.
378
379 HEAP MEMORY USED: x bytes
380
381 STACK MEMORY USED: x bytes
382
383 CLOCK CYCLES: (cycle count equation for this function) + (variable
384 used to represent cycle count for each subroutine
385 called)
386 where: (cycle count variable) = cycle count for [subroutine
387 name]
388
389 ------------------------------------------------------------------------------
390 CAUTION [optional]
391 [State any special notes, constraints or cautions for users of this function]
392
393 ------------------------------------------------------------------------------
394 */
395
396 /*----------------------------------------------------------------------------
397 ; FUNCTION CODE
398 ----------------------------------------------------------------------------*/
build_code(Word16 codvec[],Word16 sign[],Word16 cod[],Word16 h[],Word16 y[],Word16 indx[],Flag * pOverflow)399 static void build_code(
400 Word16 codvec[], /* (i) : position of pulses */
401 Word16 sign[], /* (i) : sign of d[n] */
402 Word16 cod[], /* (o) : innovative code vector */
403 Word16 h[], /* (i) : impulse response of weighted synthesis filter*/
404 Word16 y[], /* (o) : filtered innovative code */
405 Word16 indx[], /* (o) : index of 10 pulses (sign+position) */
406 Flag *pOverflow /* i/o : overflow Flag */
407 )
408 {
409 Word16 i, k, track, index, _sign[NB_PULSE];
410 Word16 *p0, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9;
411 Word32 s;
412 Word16 temp;
413 Word16 *p__sign;
414 Word16 *p_y;
415 Word16 *p_codvec;
416
417 OSCL_UNUSED_ARG(pOverflow);
418
419 memset(cod, 0, L_CODE*sizeof(*cod));
420 memset(indx, 0xFF, NB_TRACK*sizeof(*indx));
421
422 p__sign = _sign;
423
424 p0 = &codvec[0];
425
426 for (k = 0; k < NB_PULSE; k++)
427 {
428 /* read pulse position */
429 i = *(p0++);
430 /* read sign */
431
432 index = ((Word32)i * 6554) >> 15; /* index = pos/5 */
433
434 /* track = pos%5 */
435 /* track = sub (i, extract_l (L_shr (L_mult (index, 5), 1))); */
436 track = i - (index * 5);
437
438 if (sign[i] > 0)
439 {
440 cod[i] += 4096;
441 *(p__sign++) = 8192;
442
443 }
444 else
445 {
446 cod[i] -= 4096;
447 *(p__sign++) = -8192;
448 /* index = add (index, 8); */
449 index += 8;
450 }
451
452 p1 = &indx[track];
453
454 temp = *p1;
455
456 if (temp < 0)
457 {
458 *p1 = index;
459 }
460 else
461 {
462 if (((index ^ temp) & 8) == 0)
463 {
464 /* sign of 1st pulse == sign of 2nd pulse */
465
466 /* if (sub (indx[track], index) <= 0) */
467 if (temp <= index)
468 {
469 *(p1 + 5) = index;
470 }
471 else
472 {
473 *(p1 + 5) = temp;
474 *p1 = index;
475 }
476 }
477 else
478 {
479 /* sign of 1st pulse != sign of 2nd pulse */
480
481 /* if (sub ((Word16)(indx[track] & 7), (Word16)(index & 7)) <= 0) */
482 if ((temp & 7) <= (index & 7))
483 {
484 *(p1 + 5) = temp;
485 *p1 = index;
486 }
487 else
488 {
489 *(p1 + 5) = index;
490 }
491 }
492 }
493 }
494
495 p_codvec = &codvec[0];
496
497 p0 = h - *(p_codvec++);
498 p1 = h - *(p_codvec++);
499 p2 = h - *(p_codvec++);
500 p3 = h - *(p_codvec++);
501 p4 = h - *(p_codvec++);
502 p5 = h - *(p_codvec++);
503 p6 = h - *(p_codvec++);
504 p7 = h - *(p_codvec++);
505 p8 = h - *(p_codvec++);
506 p9 = h - *(p_codvec++);
507
508 p_y = y;
509
510 for (i = L_CODE; i != 0; i--)
511 {
512 p__sign = _sign;
513
514 s = (*p0++ * *(p__sign++)) >> 7;
515 s += (*p1++ * *(p__sign++)) >> 7;
516 s += (*p2++ * *(p__sign++)) >> 7;
517 s += (*p3++ * *(p__sign++)) >> 7;
518 s += (*p4++ * *(p__sign++)) >> 7;
519 s += (*p5++ * *(p__sign++)) >> 7;
520 s += (*p6++ * *(p__sign++)) >> 7;
521 s += (*p7++ * *(p__sign++)) >> 7;
522 s += (*p8++ * *(p__sign++)) >> 7;
523 s += (*p9++ * *(p__sign++)) >> 7;
524
525 *(p_y++) = (s + 0x080) >> 8;
526 }
527
528 }
529
530 /*
531 ------------------------------------------------------------------------------
532 FUNCTION NAME: code_10i40_35bits
533 ------------------------------------------------------------------------------
534 INPUT AND OUTPUT DEFINITIONS
535
536 Inputs:
537 pSeed = pointer to the Old CN generator shift register state (Word32)
538 n_param = Number of parameters to randomize (Word16)
539 param_size_table = table holding paameter sizes (Word16)
540 param[] = array to hold CN generated paramters (Word16)
541 pOverflow = pointer to overflow flag (Flag)
542
543 Outputs:
544 param[] = CN generated parameters (Word16)
545 pSeed = Updated CN generator shift register state (Word16)
546 pOverflow -> 1 if overflow occured
547
548 Returns:
549 None
550
551 Global Variables Used:
552 None
553
554 Local Variables Needed:
555 None
556
557 ------------------------------------------------------------------------------
558 FUNCTION DESCRIPTION
559
560 This function searches a 35 bit algebraic codebook containing 10 pulses in a
561 frame of 40 samples.
562
563 The code contains 10 nonzero pulses: i0...i9.
564 All pulses can have two possible amplitudes: +1 or -1.
565 The 40 positions in a subframe are divided into 5 tracks of
566 interleaved positions. Each track contains two pulses.
567 The pulses can have the following possible positions:
568
569 i0, i5 : 0, 5, 10, 15, 20, 25, 30, 35.
570 i1, i6 : 1, 6, 11, 16, 21, 26, 31, 36.
571 i2, i7 : 2, 7, 12, 17, 22, 27, 32, 37.
572 i3, i8 : 3, 8, 13, 18, 23, 28, 33, 38.
573 i4, i9 : 4, 9, 14, 19, 24, 29, 34, 39.
574
575 Each pair of pulses require 1 bit for their signs and 6 bits for their
576 positions (3 bits + 3 bits). This results in a 35 bit codebook.
577 The function determines the optimal pulse signs and positions, builds
578 the codevector, and computes the filtered codevector.
579
580 ------------------------------------------------------------------------------
581 REQUIREMENTS
582
583 None
584
585 ------------------------------------------------------------------------------
586 REFERENCES
587
588 c1035pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
589
590 ------------------------------------------------------------------------------
591 PSEUDO-CODE
592 void code_10i40_35bits (
593 Word16 x[], // (i) : target vector
594 Word16 cn[], // (i) : residual after long term prediction
595 Word16 h[], // (i) : impulse response of weighted synthesis filter
596 // h[-L_subfr..-1] must be set to zero
597 Word16 cod[], // (o) : algebraic (fixed) codebook excitation
598 Word16 y[], // (o) : filtered fixed codebook excitation
599 Word16 indx[] // (o) : index of 10 pulses (sign + position)
600 )
601 {
602 Word16 ipos[NB_PULSE], pos_max[NB_TRACK], codvec[NB_PULSE];
603 Word16 dn[L_CODE], sign[L_CODE];
604 Word16 rr[L_CODE][L_CODE], i;
605
606 cor_h_x (h, x, dn, 2);
607 set_sign12k2 (dn, cn, sign, pos_max, NB_TRACK, ipos, STEP);
608 cor_h (h, sign, rr);
609
610 search_10and8i40 (NB_PULSE, STEP, NB_TRACK,
611 dn, rr, ipos, pos_max, codvec);
612
613 build_code (codvec, sign, cod, h, y, indx);
614 for (i = 0; i < 10; i++)
615 {
616 q_p (&indx[i], i);
617 }
618 return;
619 }
620
621 ------------------------------------------------------------------------------
622 RESOURCES USED [optional]
623
624 When the code is written for a specific target processor the
625 the resources used should be documented below.
626
627 HEAP MEMORY USED: x bytes
628
629 STACK MEMORY USED: x bytes
630
631 CLOCK CYCLES: (cycle count equation for this function) + (variable
632 used to represent cycle count for each subroutine
633 called)
634 where: (cycle count variable) = cycle count for [subroutine
635 name]
636
637 ------------------------------------------------------------------------------
638 CAUTION [optional]
639 [State any special notes, constraints or cautions for users of this function]
640
641 ------------------------------------------------------------------------------
642 */
643
644 /*----------------------------------------------------------------------------
645 ; FUNCTION CODE
646 ----------------------------------------------------------------------------*/
code_10i40_35bits(Word16 x[],Word16 cn[],Word16 h[],Word16 cod[],Word16 y[],Word16 indx[],Flag * pOverflow)647 void code_10i40_35bits(
648 Word16 x[], /* (i) : target vector */
649 Word16 cn[], /* (i) : residual after long term prediction */
650 Word16 h[], /* (i) : impulse response of weighted synthesis filter
651 h[-L_subfr..-1] must be set to zero */
652 Word16 cod[], /* (o) : algebraic (fixed) codebook excitation */
653 Word16 y[], /* (o) : filtered fixed codebook excitation */
654 Word16 indx[], /* (o) : index of 10 pulses (sign + position) */
655 Flag *pOverflow /* (i/o) : overflow Flag */
656 )
657 {
658 Word16 ipos[NB_PULSE], pos_max[NB_TRACK], codvec[NB_PULSE];
659 Word16 dn[L_CODE], sign[L_CODE];
660 Word16 rr[L_CODE][L_CODE], i;
661
662 cor_h_x(h, x, dn, 2, pOverflow);
663 set_sign12k2(dn, cn, sign, pos_max, NB_TRACK, ipos, STEP, pOverflow);
664 cor_h(h, sign, rr, pOverflow);
665
666 search_10and8i40(NB_PULSE, STEP, NB_TRACK,
667 dn, rr, ipos, pos_max, codvec, pOverflow);
668
669 build_code(codvec, sign, cod, h, y, indx, pOverflow);
670 for (i = 0; i < 10; i++)
671 {
672 q_p(&indx[i], i);
673 }
674 return;
675 }
676
677