comparison libtwamr/g_pitch.c @ 367:bd4f660eb75a

libtwamr: integrate g_pitch.c
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 06 May 2024 03:08:58 +0000
parents
children
comparison
equal deleted inserted replaced
366:1588a7d9e732 367:bd4f660eb75a
1 /*
2 ********************************************************************************
3 *
4 * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001
5 * R99 Version 3.3.0
6 * REL-4 Version 4.1.0
7 *
8 ********************************************************************************
9 *
10 * File : g_pitch.c
11 * Purpose : Compute the pitch (adaptive codebook) gain.
12 *
13 ********************************************************************************
14 */
15 /*
16 ********************************************************************************
17 * MODULE INCLUDE FILE AND VERSION ID
18 ********************************************************************************
19 */
20 #include "namespace.h"
21 #include "g_pitch.h"
22
23 /*
24 ********************************************************************************
25 * INCLUDE FILES
26 ********************************************************************************
27 */
28 #include "tw_amr.h"
29 #include "typedef.h"
30 #include "basic_op.h"
31 #include "oper_32b.h"
32 #include "no_count.h"
33 #include "cnst.h"
34
35 /*
36 ********************************************************************************
37 * PUBLIC PROGRAM CODE
38 ********************************************************************************
39 */
40 /*************************************************************************
41 *
42 * FUNCTION: G_pitch
43 *
44 * PURPOSE: Compute the pitch (adaptive codebook) gain.
45 * Result in Q14 (NOTE: 12.2 bit exact using Q12)
46 *
47 * DESCRIPTION:
48 * The adaptive codebook gain is given by
49 *
50 * g = <x[], y[]> / <y[], y[]>
51 *
52 * where x[] is the target vector, y[] is the filtered adaptive
53 * codevector, and <> denotes dot product.
54 * The gain is limited to the range [0,1.2] (=0..19661 Q14)
55 *
56 *************************************************************************/
57 Word16 G_pitch ( /* o : Gain of pitch lag saturated to 1.2 */
58 enum Mode mode, /* i : AMR mode */
59 Word16 xn[], /* i : Pitch target. */
60 Word16 y1[], /* i : Filtered adaptive codebook. */
61 Word16 g_coeff[], /* i : Correlations need for gain quantization */
62 Word16 L_subfr /* i : Length of subframe. */
63 )
64 {
65 Word16 i;
66 Word16 xy, yy, exp_xy, exp_yy, gain;
67 Word32 s;
68
69 Word16 scaled_y1[L_SUBFR]; /* Usually dynamic allocation of (L_subfr) */
70
71 /* divide "y1[]" by 4 to avoid overflow */
72
73 for (i = 0; i < L_subfr; i++)
74 {
75 scaled_y1[i] = shr (y1[i], 2); move16 ();
76 }
77
78 /* Compute scalar product <y1[],y1[]> */
79
80 /* Q12 scaling / MR122 */
81 Overflow = 0; move16 ();
82 s = 1L; move32 (); /* Avoid case of all zeros */
83 for (i = 0; i < L_subfr; i++)
84 {
85 s = L_mac (s, y1[i], y1[i]);
86 }
87 test ();
88 if (Overflow == 0) /* Test for overflow */
89 {
90 exp_yy = norm_l (s);
91 yy = round (L_shl (s, exp_yy));
92 }
93 else
94 {
95 s = 1L; move32 (); /* Avoid case of all zeros */
96 for (i = 0; i < L_subfr; i++)
97 {
98 s = L_mac (s, scaled_y1[i], scaled_y1[i]);
99 }
100 exp_yy = norm_l (s);
101 yy = round (L_shl (s, exp_yy));
102 exp_yy = sub (exp_yy, 4);
103 }
104
105 /* Compute scalar product <xn[],y1[]> */
106
107 Overflow = 0; move16 ();
108 s = 1L; move32 (); /* Avoid case of all zeros */
109
110 for (i = 0; i < L_subfr; i++)
111 {
112 s = L_mac(s, xn[i], y1[i]);
113 }
114 test ();
115 if (Overflow == 0)
116 {
117 exp_xy = norm_l (s);
118 xy = round (L_shl (s, exp_xy));
119 }
120 else
121 {
122 s = 1L; move32 (); /* Avoid case of all zeros */
123 for (i = 0; i < L_subfr; i++)
124 {
125 s = L_mac (s, xn[i], scaled_y1[i]);
126 }
127 exp_xy = norm_l (s);
128 xy = round (L_shl (s, exp_xy));
129 exp_xy = sub (exp_xy, 2);
130 }
131
132 g_coeff[0] = yy; move16 ();
133 g_coeff[1] = sub (15, exp_yy); move16 ();
134 g_coeff[2] = xy; move16 ();
135 g_coeff[3] = sub (15, exp_xy); move16 ();
136
137 /* If (xy < 4) gain = 0 */
138
139 i = sub (xy, 4);
140
141 test ();
142 if (i < 0)
143 return ((Word16) 0);
144
145 /* compute gain = xy/yy */
146
147 xy = shr (xy, 1); /* Be sure xy < yy */
148 gain = div_s (xy, yy);
149
150 i = sub (exp_xy, exp_yy); /* Denormalization of division */
151 gain = shr (gain, i);
152
153 /* if(gain >1.2) gain = 1.2 */
154
155 test ();
156 if (sub (gain, 19661) > 0)
157 {
158 gain = 19661; move16 ();
159 }
160
161 test ();
162 if (sub(mode, MR122) == 0)
163 {
164 /* clear 2 LSBits */
165 gain = gain & 0xfffC; logic16 ();
166 }
167
168 return (gain);
169 }