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 <math.h>
36 : #include "prot.h"
37 : #include "ivas_prot.h"
38 : #include "wmc_auto.h"
39 : #include <assert.h>
40 :
41 :
42 : /*-------------------------------------------------------------------*
43 : * detect_strong_saturations()
44 : *
45 : * Detection of very strong saturations,
46 : * usually happens as a consequence of a heavy corrupted bitstream
47 : *-------------------------------------------------------------------*/
48 :
49 : /*! r: apply_strong_limiting flag */
50 2859836 : static int16_t detect_strong_saturations(
51 : const int16_t BER_detect, /* i : BER detect flag */
52 : int16_t *strong_saturation_cnt, /* i/o: counter of strong saturations */
53 : const float max_val, /* i : maximum absolute value */
54 : float *frame_gain /* i/o: frame gain value */
55 : )
56 : {
57 : int16_t apply_strong_limiting;
58 :
59 2859836 : apply_strong_limiting = 0;
60 :
61 2859836 : if ( BER_detect )
62 : {
63 0 : *strong_saturation_cnt = 50;
64 0 : apply_strong_limiting = 1;
65 : }
66 2859836 : else if ( max_val > 3 * IVAS_LIMITER_THRESHOLD && *strong_saturation_cnt > 0 )
67 : {
68 0 : apply_strong_limiting = 1;
69 : }
70 2859836 : else if ( max_val > 10 * IVAS_LIMITER_THRESHOLD )
71 : {
72 0 : *strong_saturation_cnt += 20;
73 0 : *strong_saturation_cnt = min( *strong_saturation_cnt, 50 );
74 0 : apply_strong_limiting = 1;
75 : }
76 : else
77 : {
78 2859836 : ( *strong_saturation_cnt )--;
79 2859836 : *strong_saturation_cnt = max( *strong_saturation_cnt, 0 );
80 : }
81 :
82 2859836 : if ( apply_strong_limiting )
83 : {
84 0 : if ( *frame_gain < 0.3f )
85 : {
86 0 : *frame_gain /= 3.0f;
87 : }
88 : else
89 : {
90 0 : apply_strong_limiting = 0;
91 : }
92 : }
93 :
94 2859836 : return apply_strong_limiting;
95 : }
96 :
97 : /*-------------------------------------------------------------------*
98 : * ivas_limiter_open()
99 : *
100 : * Allocate and initialize limiter struct
101 : *-------------------------------------------------------------------*/
102 :
103 : /*! r : limiter struct handle */
104 3275 : ivas_error ivas_limiter_open(
105 : IVAS_LIMITER_HANDLE *hLimiter_out, /* o : limiter struct handle */
106 : const int16_t max_num_channels, /* i : maximum number of I/O channels to be processed */
107 : const int32_t sampling_rate /* i : sampling rate for processing */
108 : )
109 : {
110 : int16_t i;
111 : IVAS_LIMITER_HANDLE hLimiter;
112 :
113 3275 : if ( max_num_channels <= 0 || sampling_rate <= 0 )
114 : {
115 0 : return ( IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Wrong parameters for Limiter\n" ) );
116 : }
117 :
118 3275 : if ( ( hLimiter = malloc( sizeof( IVAS_LIMITER ) ) ) == NULL )
119 : {
120 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Limiter handle\n" ) );
121 : }
122 :
123 3275 : hLimiter->max_num_channels = max_num_channels;
124 3275 : hLimiter->num_channels = max_num_channels;
125 :
126 3275 : if ( ( hLimiter->channel_ptrs = malloc( max_num_channels * sizeof( float * ) ) ) == NULL )
127 : {
128 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Limiter handle\n" ) );
129 : }
130 3275 : hLimiter->sampling_rate = sampling_rate;
131 3275 : hLimiter->gain = 1.f;
132 3275 : hLimiter->release_heuristic = 0.f;
133 3275 : hLimiter->attack_constant = powf( 0.01f, 1.0f / ( IVAS_LIMITER_ATTACK_SECONDS * sampling_rate ) );
134 3275 : hLimiter->strong_saturation_count = 0;
135 : #ifdef DEBUGGING
136 : hLimiter->cnt_frames_limited = 0;
137 : #endif
138 :
139 18465 : for ( i = 0; i < max_num_channels; ++i )
140 : {
141 15190 : hLimiter->channel_ptrs[i] = NULL;
142 : }
143 :
144 3275 : *hLimiter_out = hLimiter;
145 :
146 3275 : return IVAS_ERR_OK;
147 : }
148 :
149 :
150 : /*-------------------------------------------------------------------*
151 : * ivas_limiter_close()
152 : *
153 : * Deallocate limiter struct
154 : *-------------------------------------------------------------------*/
155 :
156 3275 : void ivas_limiter_close(
157 : IVAS_LIMITER_HANDLE *phLimiter /* i/o: pointer to limiter handle, can be NULL */
158 : )
159 : {
160 3275 : if ( phLimiter == NULL || *phLimiter == NULL )
161 : {
162 0 : return;
163 : }
164 :
165 3275 : free( ( *phLimiter )->channel_ptrs );
166 3275 : free( *phLimiter );
167 3275 : *phLimiter = NULL;
168 :
169 3275 : return;
170 : }
171 :
172 :
173 : /*-------------------------------------------------------------------*
174 : * ivas_limiter_dec()
175 : *
176 : * In-place saturation control for multichannel buffers with adaptive
177 : * release time and special handling of bit errors
178 : *-------------------------------------------------------------------*/
179 :
180 2860112 : void ivas_limiter_dec(
181 : IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */
182 : float *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */
183 : const int16_t num_channels, /* i : number of channels to be processed */
184 : const int16_t output_frame, /* i : number of samples per channel in the buffer */
185 : const int16_t BER_detect /* i : BER detect flag */
186 : )
187 : {
188 : int16_t c;
189 : float **channels;
190 :
191 : /* return early if given bad parameters */
192 2860112 : if ( hLimiter == NULL || output == NULL || output_frame <= 0 )
193 : {
194 276 : return;
195 : }
196 :
197 : /* Update number of channels and prepare pointers to the beginning of each of them */
198 2859836 : assert( num_channels <= hLimiter->max_num_channels && "Number of channels must be lower than the maximum set during limiter initialization!" );
199 2859836 : hLimiter->num_channels = min( num_channels, hLimiter->max_num_channels );
200 2859836 : channels = hLimiter->channel_ptrs;
201 :
202 12969398 : for ( c = 0; c < num_channels; ++c )
203 : {
204 10109562 : channels[c] = output[c];
205 : }
206 :
207 2859836 : limiter_process( hLimiter, output_frame, IVAS_LIMITER_THRESHOLD, BER_detect, &hLimiter->strong_saturation_count );
208 :
209 2859836 : return;
210 : }
211 :
212 :
213 : /*-------------------------------------------------------------------*
214 : * limiter_process()
215 : *
216 : * hLimiter->channel_ptrs must be set before calling this function.
217 : * Consider using a wrapper function like ivas_limiter_dec() instead
218 : * of calling this directly.
219 : *-------------------------------------------------------------------*/
220 :
221 5088116 : void limiter_process(
222 : IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */
223 : const int16_t output_frame, /* i : number of samples to be processed per channel in the I/O buffer */
224 : const float threshold, /* i : signal amplitude above which limiting starts to be applied */
225 : const int16_t BER_detect, /* i : BER detect flag */
226 : int16_t *strong_saturation_cnt /* i/o: counter of strong saturations (can be NULL) */
227 : )
228 : {
229 : int16_t i, c;
230 : float tmp, max_val;
231 : float *sample;
232 : float gain, frame_gain, attack_constant, release_constant;
233 : float releaseHeuristic;
234 : int16_t apply_limiting, apply_strong_limiting;
235 : float **output;
236 : int16_t num_channels;
237 : int32_t sampling_rate;
238 :
239 : /* return early if given nonsensical values */
240 5088116 : if ( hLimiter == NULL || output_frame <= 0 )
241 : {
242 0 : return;
243 : }
244 :
245 5088116 : apply_limiting = 1;
246 5088116 : apply_strong_limiting = 0;
247 :
248 5088116 : gain = hLimiter->gain;
249 5088116 : output = hLimiter->channel_ptrs;
250 5088116 : num_channels = hLimiter->num_channels;
251 5088116 : sampling_rate = hLimiter->sampling_rate;
252 5088116 : attack_constant = hLimiter->attack_constant;
253 :
254 : /*-----------------------------------------------------------------*
255 : * Find highest absolute peak sample value
256 : *-----------------------------------------------------------------*/
257 :
258 5088116 : max_val = 0.f;
259 :
260 1913816036 : for ( i = 0; i < output_frame; i++ )
261 : {
262 11012803020 : for ( c = 0; c < num_channels; c++ )
263 : {
264 9104075100 : tmp = fabsf( output[c][i] );
265 9104075100 : if ( tmp > max_val )
266 : {
267 107926335 : max_val = tmp;
268 : }
269 : }
270 : }
271 :
272 : /* Release heuristic
273 : *
274 : * Value ranging from 0.f to 1.f. Increases on each frame that contains
275 : * a sample with a value above threshold and decreases on each frame
276 : * with all sample values below threshold.
277 : *
278 : * Values of 0 and 1 map to the shortest and longest release time, respectively.
279 : *
280 : * The goal of this heuristic is to avoid the "pumping" effect when only
281 : * sharp transients exceed the threshold (use short release time), but also
282 : * keep the gain curve smoother if the threshold is exceeded in many frames
283 : * in a short span of time.
284 : */
285 5088116 : releaseHeuristic = hLimiter->release_heuristic;
286 :
287 5088116 : if ( max_val > threshold )
288 : {
289 33335 : frame_gain = threshold / max_val;
290 :
291 33335 : releaseHeuristic = min( 1.f, releaseHeuristic + ( 4.f * output_frame / sampling_rate ) );
292 : /* Unoptimized code for reference */
293 : /* releaseHeuristic = min( 1.f, releaseHeuristic + ( (float) 2.f * output_frame / sampling_rate / adaptiveReleaseWindowLengthInSeconds ) );
294 : * ^
295 : * React faster when release time should be increased
296 : */
297 : #ifdef DEBUGGING
298 : if ( max_val > threshold )
299 : {
300 : hLimiter->cnt_frames_limited++;
301 : }
302 : #endif
303 : }
304 : else
305 : {
306 5054781 : releaseHeuristic = max( 0.f, releaseHeuristic - ( (float) output_frame / sampling_rate ) );
307 : /* Unoptimized code for reference */
308 : /* releaseHeuristic = max( 0.f, releaseHeuristic - ( (float) 0.5f * output_frame / sampling_rate / adaptiveReleaseWindowLengthInSeconds ) );
309 : * ^
310 : * React slower when release time should be decreased
311 : */
312 :
313 : /* No samples above threshold and gain from previous frame is already 1.f,
314 : * therefore gain == 1.f for the entire frame. Skip processing. */
315 5054781 : if ( gain >= 1.f - EPSILON )
316 : {
317 4434262 : apply_limiting = 0;
318 : }
319 :
320 : /* No samples above threshold but gain from previous frame is not 1.f,
321 : * transition to gain == 1.f */
322 5054781 : frame_gain = 1.f;
323 : }
324 :
325 : /* Detection of very strong saturations */
326 5088116 : if ( strong_saturation_cnt != NULL )
327 : {
328 2859836 : apply_strong_limiting = detect_strong_saturations( BER_detect, strong_saturation_cnt, max_val, &frame_gain );
329 : }
330 :
331 : /* Limit gain reduction to 20dB. Any peaks that require gain reduction
332 : * higher than this are most likely due to bit errors during decoding */
333 5088116 : if ( frame_gain < 0.1f && !apply_strong_limiting )
334 : {
335 0 : frame_gain = 0.1f;
336 : }
337 :
338 5088116 : if ( apply_limiting )
339 : {
340 :
341 : /* 99% time constants of the gain curve
342 : *
343 : * The denominator of the second argument determines after how many
344 : * samples the gain curve will reach 99% of its target value
345 : */
346 653854 : release_constant = powf( 0.01f, 1.0f / ( 0.005f * powf( 200.f, releaseHeuristic ) * sampling_rate ) );
347 :
348 : /* Unoptimized code for reference */
349 : /* releaseTimeInSeconds = 0.005f * powf(200.f, releaseHeuristic); <-- Map heuristic value (0; 1) exponentially to range (0.005; 1)
350 : * release_constant = powf( 0.01f, 1.0f / ( releaseTimeInSeconds * sampling_rate ) );
351 : */
352 :
353 : /*-----------------------------------------------------------------*
354 : * Apply limiting
355 : *-----------------------------------------------------------------*/
356 :
357 242378974 : for ( i = 0; i < output_frame; i++ )
358 : {
359 : /* Update gain */
360 241725120 : if ( frame_gain < gain )
361 : {
362 4579520 : gain = attack_constant * ( gain - frame_gain ) + frame_gain;
363 : }
364 : else
365 : {
366 237145600 : gain = release_constant * ( gain - frame_gain ) + frame_gain;
367 : }
368 :
369 1074511000 : for ( c = 0; c < num_channels; c++ )
370 : {
371 832785880 : sample = &output[c][i];
372 :
373 : /* Apply gain */
374 832785880 : *sample = gain * ( *sample );
375 : }
376 : }
377 : }
378 :
379 : /* Save last gain and release heuristic values for next frame */
380 5088116 : hLimiter->gain = gain;
381 5088116 : hLimiter->release_heuristic = releaseHeuristic;
382 :
383 5088116 : return;
384 : }
|