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 : /*====================================================================================
34 : EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
35 : ====================================================================================*/
36 :
37 : #include <stdint.h>
38 : #include "options.h"
39 : #ifdef DEBUGGING
40 : #include "debug.h"
41 : #endif
42 : #include <math.h>
43 : #include "cnst.h"
44 : #include "prot.h"
45 : #include "rom_com.h"
46 : #include "wmc_auto.h"
47 :
48 : /*---------------------------------------------------------------------*
49 : * Local function prototypes
50 : *---------------------------------------------------------------------*/
51 :
52 : static void agc2( const float *sig_in, float *sig_out, const int16_t l_trm );
53 :
54 : /*---------------------------------------------------------------------*
55 : * enhancer()
56 : *
57 : * Enhancement of the excitation signal before synthesis
58 : *---------------------------------------------------------------------*/
59 :
60 10879511 : void enhancer(
61 : const int16_t codec_mode, /* i : flag indicating Codec Mode */
62 : const int32_t core_brate, /* i : core bitrate */
63 : const int16_t cbk_index, /* i : */
64 : const int16_t Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */
65 : const int16_t coder_type, /* i : coding type */
66 : const int16_t L_frame, /* i : frame size */
67 : const float voice_fac, /* i : subframe voicing estimation */
68 : const float stab_fac, /* i : LP filter stablility measure */
69 : const float norm_gain_code, /* i : normalized innovative cb. gain */
70 : const float gain_inov, /* i : gain of the unscaled innovation */
71 : float *gc_threshold, /* i/o: code threshold */
72 : float *code, /* i/o: innovation */
73 : float *pt_exc2, /* i/o: adapt. excitation/total exc. */
74 : const float gain_pit, /* i : Quantized pitch gain */
75 : float *dispMem /* i/o: Phase dispersion algorithm memory */
76 : )
77 : {
78 : float tmp, gain_code, new_norm_gain_code, fac;
79 : int16_t i;
80 : float pit_sharp;
81 : float excp[L_SUBFR];
82 :
83 10879511 : pit_sharp = gain_pit;
84 :
85 : /*-----------------------------------------------------------------*
86 : * Phase dispersion
87 : *
88 : * Enhance noise at low bitrates
89 : *-----------------------------------------------------------------*/
90 :
91 10879511 : i = 2; /* no dispersion */
92 10879511 : if ( Opt_AMR_WB )
93 : {
94 23740 : if ( core_brate <= ACELP_6k60 )
95 : {
96 2248 : i = 0; /* high dispersion */
97 : }
98 21492 : else if ( core_brate <= ACELP_8k85 )
99 : {
100 1816 : i = 1; /* low dispersion */
101 : }
102 : }
103 10855771 : else if ( codec_mode == MODE1 && coder_type != UNVOICED )
104 : {
105 10556727 : if ( core_brate <= ACELP_7k20 )
106 : {
107 62376 : i = 0; /* high dispersion */
108 : }
109 10494351 : else if ( ( coder_type == GENERIC || coder_type == TRANSITION || coder_type == AUDIO || coder_type == INACTIVE ) && core_brate <= ACELP_9k60 )
110 : {
111 1203848 : i = 1; /* low dispersion */
112 : }
113 : }
114 299044 : else if ( codec_mode == MODE2 )
115 : {
116 164416 : if ( ( ( coder_type != VOICED ) && cbk_index <= 2 ) || ( ( coder_type == UNVOICED ) && L_frame == L_FRAME && cbk_index <= 10 ) || ( ( coder_type == UNVOICED ) && L_frame == L_FRAME16k && cbk_index <= 14 ) )
117 : {
118 4712 : i = 0; /* high dispersion */
119 : }
120 159704 : else if ( ( coder_type != VOICED ) && ( cbk_index <= 7 ) )
121 : {
122 20264 : i = 1; /* low dispersion */
123 : }
124 : }
125 134628 : else if ( codec_mode == MODE1 && coder_type == UNVOICED && cbk_index /*uc_two_stage_flag*/ )
126 : {
127 133644 : i = 0; /* high dispersion */
128 : }
129 :
130 10879511 : phase_dispersion( norm_gain_code, gain_pit, code, i, dispMem );
131 :
132 : /*------------------------------------------------------------
133 : * Noise enhancer
134 : *
135 : * Enhance excitation on noise (modify code gain). If signal is noisy and LPC filter is stable,
136 : * move code gain 1.5 dB towards its threshold. This decreases by 3 dB noise energy variation.
137 : *-----------------------------------------------------------*/
138 :
139 10879511 : if ( norm_gain_code < *gc_threshold )
140 : {
141 5459832 : new_norm_gain_code = (float) ( norm_gain_code * 1.19f );
142 5459832 : if ( new_norm_gain_code > *gc_threshold )
143 : {
144 2119221 : new_norm_gain_code = *gc_threshold;
145 : }
146 : }
147 : else
148 : {
149 5419679 : new_norm_gain_code = (float) ( norm_gain_code / 1.19f );
150 5419679 : if ( new_norm_gain_code < *gc_threshold )
151 : {
152 2056138 : new_norm_gain_code = *gc_threshold;
153 : }
154 : }
155 10879511 : *gc_threshold = new_norm_gain_code;
156 :
157 : /* calculate new code gain */
158 10879511 : fac = stab_fac * ( 0.5f * ( 1.0f - voice_fac ) ); /* 1 = unvoiced, 0 = voiced */
159 10879511 : gain_code = fac * new_norm_gain_code + ( 1.0f - fac ) * norm_gain_code;
160 10879511 : gain_code *= gain_inov;
161 :
162 707168215 : for ( i = 0; i < L_SUBFR; i++ )
163 : {
164 696288704 : code[i] *= gain_code;
165 : }
166 :
167 : /*------------------------------------------------------------*
168 : * Pitch enhancer
169 : *
170 : * Enhance excitation on voiced (HP filtering of code). On voiced signal, filter code by a smooth HP
171 : * filter to decrease the energy of code at low frequency
172 : *------------------------------------------------------------*/
173 :
174 10879511 : if ( !Opt_AMR_WB && codec_mode == MODE1 && coder_type == UNVOICED )
175 : {
176 134628 : mvr2r( code, pt_exc2, L_SUBFR );
177 : }
178 : else
179 : {
180 10744883 : if ( Opt_AMR_WB && ( core_brate == ACELP_8k85 || core_brate == ACELP_6k60 ) )
181 : {
182 4064 : pit_sharp = gain_pit;
183 4064 : if ( pit_sharp > 1.0 )
184 : {
185 1138 : pit_sharp = 1.0;
186 : }
187 :
188 4064 : if ( pit_sharp > 0.5 )
189 : {
190 218530 : for ( i = 0; i < L_SUBFR; i++ )
191 : {
192 215168 : excp[i] = pt_exc2[i] * pit_sharp * 0.25f;
193 : }
194 : }
195 : }
196 :
197 : /*-----------------------------------------------------------------
198 : * Do a simple noncasual "sharpening": effectively an FIR
199 : * filter with coefs [-tmp 1.0 -tmp] where tmp = 0 ... 0.25
200 : * This is applied to code and added to exc2
201 : *-----------------------------------------------------------------*/
202 10744883 : if ( L_frame == L_FRAME16k )
203 : {
204 6024740 : tmp = (float) ( 0.150f * ( 1.0f + voice_fac ) ); /* 0.30=voiced, 0=unvoiced */
205 : }
206 : else
207 : {
208 4720143 : tmp = (float) ( 0.125f * ( 1.0f + voice_fac ) ); /* 0.25=voiced, 0=unvoiced */
209 : }
210 10744883 : pt_exc2[0] += code[0] - ( tmp * code[1] );
211 676927629 : for ( i = 1; i < L_SUBFR - 1; i++ )
212 : {
213 666182746 : pt_exc2[i] += code[i] - ( tmp * code[i - 1] ) - ( tmp * code[i + 1] );
214 : }
215 10744883 : pt_exc2[L_SUBFR - 1] += code[L_SUBFR - 1] - ( tmp * code[L_SUBFR - 2] );
216 :
217 10744883 : if ( Opt_AMR_WB && ( core_brate == ACELP_8k85 || core_brate == ACELP_6k60 ) )
218 : {
219 4064 : if ( pit_sharp > 0.5f )
220 : {
221 218530 : for ( i = 0; i < L_SUBFR; i++ )
222 : {
223 215168 : excp[i] += pt_exc2[i];
224 : }
225 :
226 3362 : agc2( pt_exc2, excp, L_SUBFR );
227 3362 : mvr2r( excp, pt_exc2, L_SUBFR );
228 : }
229 : }
230 : }
231 :
232 10879511 : return;
233 : }
234 :
235 : /*-----------------------------------------------------------------------*
236 : * agc2()
237 : *
238 : * Adaptive gain control
239 : *-----------------------------------------------------------------------*/
240 :
241 3362 : static void agc2(
242 : const float *sig_in, /* i : postfilter input signal */
243 : float *sig_out, /* i/o: postfilter output signal */
244 : const int16_t l_trm /* i : subframe size */
245 : )
246 : {
247 : int16_t i;
248 : float gain_in, gain_out;
249 : float g0, gain;
250 :
251 :
252 3362 : gain_out = 0.0f;
253 218530 : for ( i = 0; i < l_trm; i++ )
254 : {
255 215168 : gain_out += sig_out[i] * sig_out[i];
256 : }
257 :
258 3362 : if ( gain_out == 0.0f )
259 : {
260 0 : return;
261 : }
262 :
263 3362 : gain_in = 0.0f;
264 218530 : for ( i = 0; i < l_trm; i++ )
265 : {
266 215168 : gain_in += sig_in[i] * sig_in[i];
267 : }
268 3362 : if ( gain_in == 0.0f )
269 : {
270 0 : g0 = 0.0f;
271 : }
272 : else
273 : {
274 3362 : g0 = (float) sqrt( gain_in / gain_out );
275 : }
276 :
277 3362 : gain = g0;
278 218530 : for ( i = 0; i < l_trm; i++ )
279 : {
280 215168 : sig_out[i] *= gain;
281 : }
282 :
283 3362 : return;
284 : }
|