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 : #include "cnst.h"
40 : #include "rom_com.h"
41 : #include "prot_fx.h"
42 : #include "wmc_auto.h"
43 :
44 : /*--------------------------------------------------------------------------*
45 : * env_adj()
46 : *
47 : * Adjust the band energies of noise-fill and low resolution bands
48 : *--------------------------------------------------------------------------*/
49 :
50 1807 : void env_adj_fx(
51 : const Word16 *pulses, /* i : number of pulses per band Q0 */
52 : const Word16 length, /* i : length of spectrum Q0 */
53 : const Word16 last_sfm, /* i : index of the last band Q0 */
54 : Word16 *adj, /* o : adjustment factors for the envelope Q15 */
55 : const Word16 env_stab, /* i : envelope stability Q15 */
56 : const Word16 *sfmsize /* i : subband sizes Q0 */
57 : )
58 : {
59 : Word16 i, j, group;
60 : Word16 npul;
61 : Word16 att_state;
62 : Word16 start, len;
63 : Word16 tmp, tmp_diff;
64 : Word16 gain_adj;
65 : Word16 idx;
66 :
67 1807 : att_state = 0;
68 1807 : move16();
69 1807 : len = 0;
70 1807 : move16();
71 1807 : start = 0;
72 1807 : move16();
73 :
74 : /* Find attenuation levels */
75 53747 : FOR( i = 0; i <= last_sfm; i++ )
76 : {
77 51940 : group = sub( shr( sfmsize[i], 3 ), 1 );
78 51940 : npul = pulses[i];
79 51940 : move16();
80 :
81 51940 : IF( EQ_16( length, L_FRAME32k ) )
82 : {
83 :
84 37437 : IF( npul == 0 )
85 : {
86 : /* Noise filled band */
87 10566 : IF( LE_16( group, 1 ) )
88 : {
89 8390 : test();
90 8390 : test();
91 8390 : test();
92 8390 : test();
93 8390 : IF( i > 0 && pulses[i - 1] != 0 && pulses[i + 1] != 0 )
94 : {
95 1843 : adj[i] = 11796; /* Q15, 0.36f */
96 1843 : move16();
97 : }
98 6547 : ELSE IF( i > 0 && ( pulses[i - 1] == 0 || pulses[i + 1] == 0 ) )
99 : {
100 6475 : adj[i] = 17695; /* Q15, 0.54f */
101 6475 : move16();
102 : }
103 : ELSE
104 : {
105 72 : adj[i] = 23593; /* Q15, 0.72f */
106 72 : move16();
107 : }
108 : }
109 2176 : ELSE IF( LT_16( i, last_sfm ) )
110 : {
111 1762 : test();
112 1762 : IF( pulses[i - 1] != 0 && pulses[i + 1] != 0 )
113 : {
114 219 : adj[i] = 17695; /* Q15, 0.54f */
115 219 : move16();
116 : }
117 : ELSE
118 : {
119 1543 : adj[i] = 23593; /* Q15, 0.72f */
120 1543 : move16();
121 : }
122 : }
123 : ELSE
124 : {
125 414 : adj[i] = 23593; /* Q15, 0.72f */
126 414 : move16();
127 : }
128 :
129 10566 : if ( att_state == 0 )
130 : {
131 3933 : start = i;
132 3933 : move16();
133 : }
134 :
135 10566 : len = add( len, 1 );
136 10566 : move16();
137 10566 : att_state = 1;
138 10566 : move16();
139 : }
140 : ELSE
141 : {
142 26871 : adj[i] = MAX_16; /* Q15, 1.0f (saturated) */
143 26871 : move16();
144 26871 : IF( EQ_16( att_state, 1 ) ) /* End of attenuation region found */
145 : {
146 : /* tmp = min(1, max(0, len-ENV_ADJ_START)*(1.0f/ENV_ADJ_INCL)); */
147 3519 : tmp = round_fx_sat( L_shl_sat( L_mult0( s_max( 0, sub( len, ENV_ADJ_START_FX ) ), ENV_ADJ_INV_INCL_FX ), 16 ) ); /* Q15 (15+16-16) */
148 3519 : tmp_diff = sub( MAX_16, tmp ); /* Q15 */
149 11644 : FOR( j = start; j < i; j++ )
150 : {
151 : /* adj[j] = max(tmp + (1-tmp)*adj[j],env_stab); */
152 8125 : adj[j] = s_max( add( tmp, mult( tmp_diff, adj[j] ) ), env_stab ); /* Q15 (15+15-15) */
153 8125 : move16();
154 : }
155 3519 : len = 0;
156 3519 : move16();
157 3519 : att_state = 0;
158 3519 : move16();
159 : }
160 : }
161 : }
162 : /* length == L_FRAME16k */
163 : ELSE
164 : {
165 :
166 : /* Calculate low accuracy band attenuation */
167 14503 : gain_adj = 32767; /* Q15, 1.0f (saturated) */
168 14503 : move16();
169 :
170 14503 : test();
171 14503 : IF( npul > 0 && LT_16( npul, MAX_P_ATT ) )
172 : {
173 : /*idx = (short)(npul * att_step[group] + 0.5f) - 1; */
174 12045 : idx = sub( mult_r( shl( npul, 2 ), att_step_fx[group] ), 1 ); /* Q0 (2+13+1-16) */
175 12045 : if ( LT_16( idx, MAX_P_ATT ) )
176 : {
177 9531 : gain_adj = gain_att_fx[idx]; /* Q15 */
178 9531 : move16();
179 : }
180 : }
181 14503 : adj[i] = gain_adj;
182 14503 : move16();
183 : }
184 : }
185 :
186 : /* Check if the sequence ended with an attenuation region */
187 1807 : IF( EQ_16( att_state, 1 ) )
188 : {
189 : /* tmp = min(1, max(0, len-ENV_ADJ_START)*(1.0f/ENV_ADJ_INCL)); */
190 414 : tmp = round_fx_sat( L_shl_sat( L_mult0( s_max( 0, sub( len, ENV_ADJ_START_FX ) ), ENV_ADJ_INV_INCL_FX ), 16 ) ); /* Q15 (15+16-16) */
191 414 : tmp_diff = sub( MAX_16, tmp ); /* Q15 */
192 414 : move16();
193 2855 : FOR( j = start; j < i; j++ )
194 : {
195 :
196 : /* adj[j] = max(tmp + (1-tmp)*adj[j],env_stab); */
197 2441 : adj[j] = s_max( add( tmp, mult( tmp_diff, adj[j] ) ), env_stab ); /* Q15 (15+15-15) */
198 2441 : move16();
199 : }
200 : }
201 :
202 1807 : return;
203 : }
|