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/c8_31pf.c
35 Functions:
36
37 Date: 05/26/2000
38
39 ------------------------------------------------------------------------------
40 REVISION HISTORY
41
42 Description: Modified to pass overflow flag through to basic math function.
43 The flag is passed back to the calling function by pointer reference.
44
45 Description: Optimized file to reduce clock cycle usage. Updated copyright
46 year. Removed unnecessary include files and unused #defines.
47
48 Description: Changed round function name to pv_round to avoid conflict with
49 round function in C standard library.
50
51 Description: Replaced "int" and/or "char" with OSCL defined types.
52
53 Description:
54
55 ------------------------------------------------------------------------------
56 MODULE DESCRIPTION
57
58 Purpose : Searches a 31 bit algebraic codebook containing
59 : 8 pulses in a frame of 40 samples.
60 : in the same manner as GSM-EFR
61 ------------------------------------------------------------------------------
62 */
63
64 /*----------------------------------------------------------------------------
65 ; INCLUDES
66 ----------------------------------------------------------------------------*/
67 #include "c8_31pf.h"
68 #include "typedef.h"
69 #include "cnst.h"
70 #include "inv_sqrt.h"
71 #include "cor_h.h"
72 #include "cor_h_x2.h"
73 #include "set_sign.h"
74 #include "s10_8pf.h"
75 #include "basic_op.h"
76
77 /*----------------------------------------------------------------------------
78 ; MACROS
79 ; Define module specific macros here
80 ----------------------------------------------------------------------------*/
81
82 /*----------------------------------------------------------------------------
83 ; DEFINES
84 ; Include all pre-processor statements here. Include conditional
85 ; compile variables also.
86 ----------------------------------------------------------------------------*/
87 #define NB_PULSE 8
88
89 /* define values/representation for output codevector and sign */
90 #define POS_CODE 8191
91 #define NEG_CODE 8191
92 #define POS_SIGN 32767
93 #define NEG_SIGN (Word16) (-32768L)
94
95 /*----------------------------------------------------------------------------
96 ; LOCAL FUNCTION DEFINITIONS
97 ; Function Prototype declaration
98 ----------------------------------------------------------------------------*/
99
100 /*----------------------------------------------------------------------------
101 ; LOCAL VARIABLE DEFINITIONS
102 ; Variable declaration - defined here and used outside this module
103 ----------------------------------------------------------------------------*/
104
105 /*----------------------------------------------------------------------------
106 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
107 ; Declare variables used in this module but defined elsewhere
108 ----------------------------------------------------------------------------*/
109
110 /*
111 ------------------------------------------------------------------------------
112 FUNCTION NAME:
113 ------------------------------------------------------------------------------
114 INPUT AND OUTPUT DEFINITIONS
115
116 Inputs:
117 codvec[] Array of type Word16 -- position of pulses
118 sign[] Array of type Word16 -- sign of pulses
119 h[] Array of type Word16 -- impulse response of
120 weighted synthesis filter
121 Outputs:
122 cod[] Array of type Word16 -- innovative code vector
123 y[] Array of type Word16 -- filtered innovative code
124 sign_indx[] Array of type Word16 -- signs of 4 pulses (signs only)
125 pos_indx[] Array of type Word16 --
126 position index of 8 pulses(position only)
127
128 pOverflow Pointer to Flag -- set when overflow occurs
129
130 Returns:
131 indx
132
133 Global Variables Used:
134 None
135
136 Local Variables Needed:
137
138 ------------------------------------------------------------------------------
139 FUNCTION DESCRIPTION
140
141
142 ------------------------------------------------------------------------------
143 REQUIREMENTS
144
145 None
146
147 ------------------------------------------------------------------------------
148 REFERENCES
149
150 [1] c8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
151
152 ------------------------------------------------------------------------------
153 PSEUDO-CODE
154
155 ------------------------------------------------------------------------------
156 RESOURCES USED [optional]
157
158 When the code is written for a specific target processor the
159 the resources used should be documented below.
160
161 HEAP MEMORY USED: x bytes
162
163 STACK MEMORY USED: x bytes
164
165 CLOCK CYCLES: (cycle count equation for this function) + (variable
166 used to represent cycle count for each subroutine
167 called)
168 where: (cycle count variable) = cycle count for [subroutine
169 name]
170
171 ------------------------------------------------------------------------------
172 CAUTION [optional]
173 [State any special notes, constraints or cautions for users of this function]
174
175 ------------------------------------------------------------------------------
176 */
177
178 /*************************************************************************
179 *
180 * FUNCTION: build_code()
181 *
182 * PURPOSE: Builds the codeword, the filtered codeword and a
183 * linear uncombined version of the index of the
184 * codevector, based on the signs and positions of 8 pulses.
185 *
186 *************************************************************************/
187
build_code(Word16 codvec[],Word16 sign[],Word16 cod[],Word16 h[],Word16 y[],Word16 sign_indx[],Word16 pos_indx[],Flag * pOverflow)188 static void build_code(
189 Word16 codvec[], /* i : position of pulses */
190 Word16 sign[], /* i : sign of d[n] */
191 Word16 cod[], /* o : innovative code vector */
192 Word16 h[], /* i : impulse response of weighted synthesis filter*/
193 Word16 y[], /* o : filtered innovative code */
194 Word16 sign_indx[], /* o : signs of 4 pulses (signs only) */
195 Word16 pos_indx[], /* o : position index of 8 pulses(position only) */
196 Flag * pOverflow /* o : Flag set when overflow occurs */
197 )
198 {
199 Word16 i;
200 Word16 j;
201 Word16 k;
202 Word16 track;
203 Word16 sign_index;
204 Word16 pos_index;
205 Word16 _sign[NB_PULSE];
206
207 Word16 *p0;
208 Word16 *p1;
209 Word16 *p2;
210 Word16 *p3;
211 Word16 *p4;
212 Word16 *p5;
213 Word16 *p6;
214 Word16 *p7;
215
216 Word16 *p_cod = &cod[0];
217 Word16 *p_codvec = &codvec[0];
218
219 Word32 s;
220
221 for (i = 0; i < L_CODE; i++)
222 {
223 *(p_cod++) = 0;
224 }
225
226 for (i = 0; i < NB_TRACK_MR102; i++)
227 {
228 pos_indx[i] = -1;
229 sign_indx[i] = -1;
230 }
231
232 for (k = 0; k < NB_PULSE; k++)
233 {
234 /* read pulse position */
235 i = codvec[k];
236 /* read sign */
237 j = sign[i];
238
239 pos_index = i >> 2; /* index = pos/4 */
240
241 track = i & 3; /* track = pos%4 */
242
243 if (j > 0)
244 {
245 cod[i] = (Word16)((Word32) cod[i] + POS_CODE);
246
247 _sign[k] = POS_SIGN;
248 sign_index = 0; /* bit=0 -> positive pulse */
249 }
250 else
251 {
252 cod[i] = (Word16)((Word32) cod[i] - NEG_CODE);
253
254 _sign[k] = NEG_SIGN;
255 sign_index = 1; /* bit=1 => negative pulse */
256 /* index = add (index, 8); 1 = negative old code */
257 }
258
259 if (pos_indx[track] < 0)
260 { /* first set first NB_TRACK pulses */
261 pos_indx[track] = pos_index;
262 sign_indx[track] = sign_index;
263 }
264 else
265 { /* 2nd row of pulses , test if positions needs to be switched */
266 if (((sign_index ^ sign_indx[track]) & 1) == 0)
267 {
268 /* sign of 1st pulse == sign of 2nd pulse */
269
270 if (pos_indx[track] <= pos_index)
271 { /* no swap */
272 pos_indx[track + NB_TRACK_MR102] = pos_index;
273 }
274 else
275 { /* swap*/
276 pos_indx[track + NB_TRACK_MR102] = pos_indx[track];
277
278 pos_indx[track] = pos_index;
279 sign_indx[track] = sign_index;
280 }
281 }
282 else
283 {
284 /* sign of 1st pulse != sign of 2nd pulse */
285
286 if (pos_indx[track] <= pos_index)
287 { /*swap*/
288 pos_indx[track + NB_TRACK_MR102] = pos_indx[track];
289
290 pos_indx[track] = pos_index;
291 sign_indx[track] = sign_index;
292 }
293 else
294 { /*no swap */
295 pos_indx[track + NB_TRACK_MR102] = pos_index;
296 }
297 }
298 }
299 }
300
301 p0 = h - *(p_codvec++);
302 p1 = h - *(p_codvec++);
303 p2 = h - *(p_codvec++);
304 p3 = h - *(p_codvec++);
305 p4 = h - *(p_codvec++);
306 p5 = h - *(p_codvec++);
307 p6 = h - *(p_codvec++);
308 p7 = h - *(p_codvec);
309
310 for (i = 0; i < L_CODE; i++)
311 {
312 s = 0;
313
314 s =
315 L_mac(
316 s,
317 *p0++,
318 _sign[0],
319 pOverflow);
320 s =
321 L_mac(
322 s,
323 *p1++,
324 _sign[1],
325 pOverflow);
326 s =
327 L_mac(
328 s,
329 *p2++,
330 _sign[2],
331 pOverflow);
332 s =
333 L_mac(
334 s,
335 *p3++,
336 _sign[3],
337 pOverflow);
338 s =
339 L_mac(
340 s,
341 *p4++,
342 _sign[4],
343 pOverflow);
344 s =
345 L_mac(
346 s,
347 *p5++,
348 _sign[5],
349 pOverflow);
350 s =
351 L_mac(
352 s,
353 *p6++,
354 _sign[6],
355 pOverflow);
356 s =
357 L_mac(
358 s,
359 *p7++,
360 _sign[7],
361 pOverflow);
362
363 y[i] =
364 pv_round(
365 s,
366 pOverflow);
367
368 } /* for (i = 0; i < L_CODE; i++) */
369
370 } /* build_code */
371
372 /****************************************************************************/
373
374 /*
375 ------------------------------------------------------------------------------
376 FUNCTION NAME: compress_code()
377 ------------------------------------------------------------------------------
378 INPUT AND OUTPUT DEFINITIONS
379
380 Inputs:
381
382 Outputs:
383
384 Returns:
385 None
386
387 Global Variables Used:
388 None
389
390 Local Variables Needed:
391
392 ------------------------------------------------------------------------------
393 FUNCTION DESCRIPTION
394
395 FUNCTION:
396
397 PURPOSE: compression of three indeces [0..9] to one 10 bit index
398 minimizing the phase shift of a bit error.
399
400 ------------------------------------------------------------------------------
401 REQUIREMENTS
402
403 None
404
405 ------------------------------------------------------------------------------
406 REFERENCES
407
408 [1] c8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
409
410 ------------------------------------------------------------------------------
411 PSEUDO-CODE
412
413 ------------------------------------------------------------------------------
414 RESOURCES USED [optional]
415
416 When the code is written for a specific target processor the
417 the resources used should be documented below.
418
419 HEAP MEMORY USED: x bytes
420
421 STACK MEMORY USED: x bytes
422
423 CLOCK CYCLES: (cycle count equation for this function) + (variable
424 used to represent cycle count for each subroutine
425 called)
426 where: (cycle count variable) = cycle count for [subroutine
427 name]
428
429 ------------------------------------------------------------------------------
430 CAUTION [optional]
431 [State any special notes, constraints or cautions for users of this function]
432
433 ------------------------------------------------------------------------------
434 */
435
compress10(Word16 pos_indxA,Word16 pos_indxB,Word16 pos_indxC,Flag * pOverflow)436 static Word16 compress10(
437 Word16 pos_indxA, /* i : signs of 4 pulses (signs only) */
438 Word16 pos_indxB, /* i : position index of 8 pulses (pos only) */
439 Word16 pos_indxC, /* i : position and sign of 8 pulses (compressed) */
440 Flag *pOverflow) /* o : Flag set when overflow occurs */
441 {
442 Word16 indx;
443 Word16 ia;
444 Word16 ib;
445 Word16 ic;
446
447 Word32 tempWord32;
448
449 OSCL_UNUSED_ARG(pOverflow);
450
451 ia = pos_indxA >> 1;
452
453 ib = pos_indxB >> 1;
454
455 tempWord32 = ((Word32) ib * 5) << 1;
456
457 tempWord32 = tempWord32 >> 1;
458
459 ib = (Word16) tempWord32;
460
461 ic = pos_indxC >> 1;
462
463 tempWord32 = ((Word32) ic * 25) << 1;
464
465 tempWord32 = tempWord32 >> 1;
466
467 ic = (Word16) tempWord32;
468
469 ib += ic;
470
471 ib += ia;
472
473 indx = ib << 3;
474
475 ia = pos_indxA & 1;
476
477 ib = ((Word16)(pos_indxB & 1)) << 1;
478
479 ic = ((Word16)(pos_indxC & 1)) << 2;
480
481 ib += ic;
482
483 ib += ia;
484
485 indx += ib;
486
487 return indx;
488
489 }
490
491 /****************************************************************************/
492
493 /*
494 ------------------------------------------------------------------------------
495 FUNCTION NAME: compress_code()
496 ------------------------------------------------------------------------------
497 INPUT AND OUTPUT DEFINITIONS
498
499 Inputs:
500 sign_indx Array of type Word16 -- signs of 4 pulses (signs only)
501 pos_indx Array of type Word16 -- position index of 8 pulses
502 (position only)
503
504 Outputs:
505 indx Array of type Word16 -- position and sign of 8 pulses
506 (compressed)
507 pOverflow Pointer to Flag -- set when overflow occurs
508
509 Returns:
510 None
511
512 Global Variables Used:
513 None
514
515 Local Variables Needed:
516 None
517
518 ------------------------------------------------------------------------------
519 FUNCTION DESCRIPTION
520
521 PURPOSE: compression of the linear codewords to 4+three indeces
522 one bit from each pulse is made robust to errors by
523 minimizing the phase shift of a bit error.
524 4 signs (one for each track)
525 i0,i4,i1 => one index (7+3) bits, 3 LSBs more robust
526 i2,i6,i5 => one index (7+3) bits, 3 LSBs more robust
527 i3,i7 => one index (5+2) bits, 2-3 LSbs more robust
528
529 ------------------------------------------------------------------------------
530 REQUIREMENTS
531
532 None
533
534 ------------------------------------------------------------------------------
535 REFERENCES
536
537 [1] c3_14pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
538
539 ------------------------------------------------------------------------------
540 PSEUDO-CODE
541
542 ------------------------------------------------------------------------------
543 RESOURCES USED [optional]
544
545 When the code is written for a specific target processor the
546 the resources used should be documented below.
547
548 HEAP MEMORY USED: x bytes
549
550 STACK MEMORY USED: x bytes
551
552 CLOCK CYCLES: (cycle count equation for this function) + (variable
553 used to represent cycle count for each subroutine
554 called)
555 where: (cycle count variable) = cycle count for [subroutine
556 name]
557
558 ------------------------------------------------------------------------------
559 CAUTION [optional]
560 [State any special notes, constraints or cautions for users of this function]
561
562 ------------------------------------------------------------------------------
563 */
564
compress_code(Word16 sign_indx[],Word16 pos_indx[],Word16 indx[],Flag * pOverflow)565 static void compress_code(
566 Word16 sign_indx[], /* i : signs of 4 pulses (signs only) */
567 Word16 pos_indx[], /* i : position index of 8 pulses (position only) */
568 Word16 indx[], /* o : position and sign of 8 pulses (compressed) */
569 Flag *pOverflow) /* o : Flag set when overflow occurs */
570 {
571 Word16 i;
572 Word16 ia;
573 Word16 ib;
574 Word16 ic;
575
576 Word16 *p_indx = &indx[0];
577 Word16 *p_sign_indx = &sign_indx[0];
578
579 Word32 tempWord32;
580
581 for (i = 0; i < NB_TRACK_MR102; i++)
582 {
583 *(p_indx++) = *(p_sign_indx++);
584 }
585
586 /* First index
587 indx[NB_TRACK] = (ia/2+(ib/2)*5 +(ic/2)*25)*8 + ia%2 + (ib%2)*2 + (ic%2)*4; */
588
589 indx[NB_TRACK_MR102] =
590 compress10(
591 pos_indx[0],
592 pos_indx[4],
593 pos_indx[1],
594 pOverflow);
595
596 /* Second index
597 indx[NB_TRACK+1] = (ia/2+(ib/2)*5 +(ic/2)*25)*8 + ia%2 + (ib%2)*2 + (ic%2)*4; */
598
599 indx[NB_TRACK_MR102+1] =
600 compress10(
601 pos_indx[2],
602 pos_indx[6],
603 pos_indx[5],
604 pOverflow);
605
606 /*
607 Third index
608 if ((ib/2)%2 == 1)
609 indx[NB_TRACK+2] = ((((4-ia/2) + (ib/2)*5)*32+12)/25)*4 + ia%2 + (ib%2)*2;
610 else
611 indx[NB_TRACK+2] = ((((ia/2) + (ib/2)*5)*32+12)/25)*4 + ia%2 + (ib%2)*2;
612 */
613
614 ib = pos_indx[7] >> 1;
615
616 ib &= 1;
617
618 ia = pos_indx[3] >> 1;
619
620 if (ib == 1)
621 {
622 ia = 4 - ia;
623 }
624
625 ib = pos_indx[7] >> 1;
626
627 tempWord32 = ((Word32) ib * 5) << 1;
628
629 tempWord32 = tempWord32 >> 1;
630
631 ib = (Word16) tempWord32;
632
633 ib += ia;
634
635 ib <<= 5;
636
637 ib += 12;
638
639 ic = (Word16)(((Word32) ib * 1311) >> 15);
640
641 ic <<= 2;
642
643 ia = pos_indx[3] & 1;
644
645 ib = ((Word16)(pos_indx[7] & 1)) << 1;
646
647 ib += ic;
648
649 ib += ia;
650
651 indx[NB_TRACK_MR102+2] = ib;
652
653 } /* compress_code */
654
655
656 /****************************************************************************/
657
658 /*
659 ------------------------------------------------------------------------------
660 FUNCTION NAME: code_8i40_31bits()
661 ------------------------------------------------------------------------------
662 INPUT AND OUTPUT DEFINITIONS
663
664 Inputs:
665 x Array of type Word16 -- target vector
666 cn Array of type Word16 -- residual after long term prediction
667 h Array of type Word16 -- impulse response of weighted synthesis filter
668
669
670 Outputs:
671 cod Array of type Word16 -- algebraic (fixed) codebook excitation
672 y Array of type Word16 -- filtered fixed codebook excitation
673 indx Array of type Word16 -- index of 8 pulses (signs+positions)
674 pOverflow Pointer to Flag -- set when overflow occurs
675
676 Returns:
677 None
678
679 Global Variables Used:
680 None
681
682 Local Variables Needed:
683 None
684
685 ------------------------------------------------------------------------------
686 FUNCTION DESCRIPTION
687
688 FUNCTION:
689
690 PURPOSE: Searches a 31 bit algebraic codebook containing 8 pulses
691 in a frame of 40 samples.
692
693 DESCRIPTION:
694 The code contains 8 nonzero pulses: i0...i7.
695 All pulses can have two possible amplitudes: +1 or -1.
696 The 40 positions in a subframe are divided into 4 tracks of
697 interleaved positions. Each track contains two pulses.
698 The pulses can have the following possible positions:
699
700 i0, i4 : 0, 4, 8, 12, 16, 20, 24, 28, 32, 36
701 i1, i5 : 1, 5, 9, 13, 17, 21, 25, 29, 33, 37
702 i2, i6 : 2, 6, 10, 14, 18, 22, 26, 30, 34, 38
703 i3, i7 : 3, 7, 11, 15, 19, 23, 27, 31, 35, 39
704
705 Each pair of pulses require 1 bit for their signs. The positions
706 are encoded together 3,3 and 2 resulting in
707 (7+3) + (7+3) + (5+2) bits for their
708 positions. This results in a 31 (4 sign and 27 pos) bit codebook.
709 The function determines the optimal pulse signs and positions, builds
710 the codevector, and computes the filtered codevector.
711
712 ------------------------------------------------------------------------------
713 REQUIREMENTS
714
715 None
716
717 ------------------------------------------------------------------------------
718 REFERENCES
719
720 [1] c8_31pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
721
722 ------------------------------------------------------------------------------
723 PSEUDO-CODE
724
725 ------------------------------------------------------------------------------
726 RESOURCES USED [optional]
727
728 When the code is written for a specific target processor the
729 the resources used should be documented below.
730
731 HEAP MEMORY USED: x bytes
732
733 STACK MEMORY USED: x bytes
734
735 CLOCK CYCLES: (cycle count equation for this function) + (variable
736 used to represent cycle count for each subroutine
737 called)
738 where: (cycle count variable) = cycle count for [subroutine
739 name]
740
741 ------------------------------------------------------------------------------
742 CAUTION [optional]
743 [State any special notes, constraints or cautions for users of this function]
744
745 ------------------------------------------------------------------------------
746 */
code_8i40_31bits(Word16 x[],Word16 cn[],Word16 h[],Word16 cod[],Word16 y[],Word16 indx[],Flag * pOverflow)747 void code_8i40_31bits(
748 Word16 x[], /* i : target vector */
749 Word16 cn[], /* i : residual after long term prediction */
750 Word16 h[], /* i : impulse response of weighted synthesis
751 filter */
752 Word16 cod[], /* o : algebraic (fixed) codebook excitation */
753 Word16 y[], /* o : filtered fixed codebook excitation */
754 Word16 indx[], /* o : 7 Word16, index of 8 pulses (signs+positions) */
755 Flag *pOverflow /* o : Flag set when overflow occurs */
756 )
757 {
758 Word16 ipos[NB_PULSE];
759 Word16 pos_max[NB_TRACK_MR102];
760 Word16 codvec[NB_PULSE];
761
762 Word16 dn[L_CODE];
763 Word16 sign[L_CODE];
764
765 Word16 rr[L_CODE][L_CODE];
766 Word16 linear_signs[NB_TRACK_MR102];
767 Word16 linear_codewords[NB_PULSE];
768
769 cor_h_x2(
770 h,
771 x,
772 dn,
773 2,
774 NB_TRACK_MR102,
775 STEP_MR102,
776 pOverflow);
777
778 /* 2 = use GSMEFR scaling */
779
780 set_sign12k2(
781 dn,
782 cn,
783 sign,
784 pos_max,
785 NB_TRACK_MR102,
786 ipos,
787 STEP_MR102,
788 pOverflow);
789
790 /* same setsign alg as GSM-EFR new constants though*/
791
792 cor_h(
793 h,
794 sign,
795 rr,
796 pOverflow);
797
798 search_10and8i40(
799 NB_PULSE,
800 STEP_MR102,
801 NB_TRACK_MR102,
802 dn,
803 rr,
804 ipos,
805 pos_max,
806 codvec,
807 pOverflow);
808
809 build_code(
810 codvec,
811 sign,
812 cod,
813 h,
814 y,
815 linear_signs,
816 linear_codewords,
817 pOverflow);
818
819 compress_code(
820 linear_signs,
821 linear_codewords,
822 indx,
823 pOverflow);
824
825 } /* code_8i40_31bits */
826
827
828
829