Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : #include <stdint.h>
34 : #include "options.h"
35 : #include "rom_com.h"
36 : #include "prot_fx.h"
37 :
38 : /*===================================================================*/
39 : /* FUNCTION : dequantize_uvg_fx() */
40 : /*-------------------------------------------------------------------*/
41 : /* PURPOSE : This function returns the quantized gain
42 : vector given the indices in the gain
43 : quantization tables */
44 : /*-------------------------------------------------------------------*/
45 : /* INPUT ARGUMENTS : */
46 : /* _ (Word16) iG1 : index into UVG1CB_fx table (Q0) */
47 : /* _ (Word16*) iG2 : indices into UVG2CB_fx (Q0) */
48 : /* - (Word32) Fs : output sampling rate */
49 : /*-------------------------------------------------------------------*/
50 : /* OUTPUT ARGUMENTS : */
51 : /* _ (Word16*) G : Output quantized gain vector */
52 : /*-------------------------------------------------------------------*/
53 : /* INPUT/OUTPUT ARGUMENTS : */
54 : /* _ None. */
55 : /*-------------------------------------------------------------------*/
56 : /* RETURN ARGUMENTS : */
57 : /* _ None. */
58 : /*===================================================================*/
59 0 : Word16 dequantize_uvg_fx(
60 : const Word16 iG1, /* i: gain 1 index */
61 : const Word16 *iG2, /* i: gain 2 index */
62 : Word16 *G, /* o: quantized gain */
63 : const Word16 bwidth_fx, /* i: bandwidth */
64 : const Word16 do_scale )
65 : {
66 : Word16 i, k;
67 0 : const Word16( *UVG1CB )[2] = NULL;
68 0 : const Word16( *UVG2CB1 )[5] = NULL;
69 0 : const Word16( *UVG2CB2 )[5] = NULL;
70 : Word16 frac, exp, sc;
71 : Word32 L_tmp;
72 0 : Word16 Q_gain = 0;
73 0 : move16();
74 :
75 0 : test();
76 0 : IF( EQ_16( bwidth_fx, NB ) )
77 : {
78 0 : UVG1CB = UVG1CB_NB_FX;
79 0 : move16();
80 0 : UVG2CB1 = UVG2CB1_NB_FX;
81 0 : move16();
82 0 : UVG2CB2 = UVG2CB2_NB_FX;
83 0 : move16();
84 : }
85 0 : ELSE IF( EQ_16( bwidth_fx, WB ) || EQ_16( bwidth_fx, SWB ) )
86 : {
87 0 : test();
88 0 : UVG1CB = UVG1CB_WB_FX;
89 0 : move16();
90 0 : UVG2CB1 = UVG2CB1_WB_FX;
91 0 : move16();
92 0 : UVG2CB2 = UVG2CB2_WB_FX;
93 0 : move16();
94 : }
95 :
96 0 : test();
97 0 : IF( !do_scale )
98 : {
99 0 : sc = 11;
100 0 : move16();
101 : }
102 : ELSE
103 : {
104 0 : test();
105 0 : IF( ( LT_16( UVG1CB[iG1][0], 4096 ) ) && ( LT_16( UVG1CB[iG1][1], 4096 ) ) ) /* if x < 1, where 10^x is used for gain computation */
106 : {
107 0 : sc = 8;
108 0 : move16();
109 0 : Q_gain = 3;
110 0 : move16();
111 : }
112 : ELSE
113 : {
114 0 : sc = 11;
115 0 : move16();
116 : }
117 : }
118 :
119 0 : FOR( i = 0; i < 2; i++ )
120 : {
121 0 : FOR( k = 0; k < 5; k++ )
122 : {
123 0 : IF( i == 0 )
124 : {
125 : /* pow(10.0, UVG1CB[iG1][i]) = pow(2.0,UVG1CB[iG1][i]*3.321928 */
126 0 : L_tmp = L_mult( UVG1CB[iG1][i], 27213 ); /* Q(13+13+1)->Q27 */
127 0 : L_tmp = L_shr_r( L_tmp, 11 ); /* Q16 */
128 0 : frac = L_Extract_lc( L_tmp, &exp );
129 0 : frac = extract_l( Pow2( 14, frac ) );
130 0 : G[i * 5 + k] = round_fx( L_shl( L_mult( frac, UVG2CB1[iG2[i]][k] ), sub( exp, sc ) ) ); /* Q0 */
131 0 : move16();
132 : }
133 0 : ELSE IF( EQ_16( i, 1 ) )
134 : {
135 0 : L_tmp = L_mult( UVG1CB[iG1][i], 27213 ); /* Q(13+13+1)->Q27 */
136 0 : L_tmp = L_shr_r( L_tmp, 11 ); /* Q16 */
137 0 : frac = L_Extract_lc( L_tmp, &exp );
138 0 : frac = extract_l( Pow2( 14, frac ) );
139 0 : G[i * 5 + k] = round_fx( L_shl( L_mult( frac, UVG2CB2[iG2[i]][k] ), sub( exp, sc ) ) ); /* Q0 */
140 0 : move16();
141 : }
142 : }
143 : }
144 0 : return Q_gain;
145 : }
146 :
147 : /*===================================================================*/
148 : /* FUNCTION : generate_nelp_excitation_fx */
149 : /*-------------------------------------------------------------------*/
150 : /* PURPOSE : This function computes the random
151 : excitation scaled by gain */
152 : /*-------------------------------------------------------------------*/
153 : /* INPUT ARGUMENTS : */
154 : /* _ (Word16*) Gains : Gain vector (Q_exc) */
155 : /* _ (Word16) gain_fac : gain factor (Q14) */
156 : /*-------------------------------------------------------------------*/
157 : /* OUTPUT ARGUMENTS : */
158 : /* _ (Word16*) seed : Random seed (Q0) */
159 : /* _ (Word16*) output : excitation output (Q_exc) */
160 : /*-------------------------------------------------------------------*/
161 : /* INPUT/OUTPUT ARGUMENTS : */
162 : /* _ None. */
163 : /*-------------------------------------------------------------------*/
164 : /* RETURN ARGUMENTS : */
165 : /* _ None. */
166 : /*===================================================================*/
167 0 : void generate_nelp_excitation_fx(
168 : Word16 *seed, /* i/o: random number seed */
169 : const Word16 *Gains, /* i : excitation gains Q_exc*/
170 : Word16 *output, /* o : excitation output */
171 : const Word16 gain_fac /* i : gain factor */
172 : )
173 : {
174 : Word16 i, len, j;
175 : Word16 tmp[31], tmp1[31], tmpf, L16;
176 : Word16 k1, k2, I[31], tmpi;
177 : Word32 L32;
178 : Word16 cnt;
179 :
180 0 : FOR( i = 0; i < 10; i++ )
181 : {
182 0 : IF( EQ_16( i, 9 ) )
183 : {
184 0 : len = 31;
185 0 : move16();
186 0 : cnt = 8;
187 0 : move16();
188 : }
189 : ELSE
190 : {
191 0 : len = 25;
192 0 : move16();
193 0 : cnt = 6;
194 0 : move16();
195 : }
196 :
197 0 : FOR( j = 0; j < len; j++ )
198 : {
199 0 : L32 = L_mult0( *seed, 0x0209 ); /* L32 = *seed*521; */
200 :
201 0 : L16 = extract_l( L_add( L32, 259 ) );
202 0 : *seed = L16;
203 0 : move16(); /* Q0 */
204 0 : tmp[j] = *seed;
205 0 : move16(); /* Q15, tmp[j]=*seed/32768 */
206 :
207 0 : tmp1[j] = abs_s( tmp[j] );
208 0 : I[j] = j;
209 0 : move16();
210 : }
211 :
212 0 : j = sub( len, 1 );
213 0 : FOR( k1 = 0; k1 < j; k1++ )
214 : {
215 0 : FOR( k2 = add( k1, 1 ); k2 < len; k2++ )
216 : {
217 0 : IF( GT_16( tmp1[k2], tmp1[k1] ) )
218 : {
219 0 : tmpi = I[k2];
220 0 : move16();
221 0 : tmpf = tmp1[k2];
222 0 : move16();
223 0 : tmp1[k2] = tmp1[k1];
224 0 : move16();
225 0 : I[k2] = I[k1];
226 0 : move16();
227 0 : tmp1[k1] = tmpf;
228 0 : move16();
229 0 : I[k1] = tmpi;
230 0 : move16();
231 : }
232 : }
233 : }
234 :
235 : /*using a factor of 1.37 to compensate for the ~ 2.5 ( or 2.73) dB diff between this scheme and EVS-UV */
236 0 : FOR( j = 0; j < cnt; j++ )
237 : {
238 0 : L16 = mult_r( tmp[I[j]], gain_fac ); /* Q14 */
239 0 : L16 = mult_r( L16, 0x6EDA ); /* Q13 */
240 :
241 0 : output[i * 25 + I[j]] = round_fx( L_shl( L_mult( L16, Gains[i] ), 2 ) ); /* Q_exc */
242 0 : move16();
243 : }
244 0 : FOR( ; j < len; j++ )
245 : {
246 0 : output[i * 25 + I[j]] = 0;
247 0 : move16();
248 : }
249 : }
250 0 : }
|