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 "ivas_prot.h"
37 : #include "ivas_cnst.h"
38 : #include "ivas_rom_com.h"
39 : #include "ivas_rom_enc.h"
40 : #include <assert.h>
41 : #include "prot.h"
42 : #include "wmc_auto.h"
43 : /* used only for norm_s in the code_length_from_count function */
44 : #include "stl.h"
45 :
46 :
47 : /*---------------------------------------------------------------
48 : * log_base2()
49 : *
50 : *
51 : * ---------------------------------------------------------------*/
52 :
53 204196 : static double log_base2(
54 : double x )
55 : {
56 204196 : return log( x ) * INV_LOG_2;
57 : }
58 :
59 : /*---------------------------------------------------------------
60 : * get_sign()
61 : *
62 : *
63 : * ---------------------------------------------------------------*/
64 :
65 439814 : static int16_t get_sign( int16_t n )
66 : {
67 439814 : return (uint16_t) n >> 15; /* extract the sign bit */
68 : }
69 :
70 :
71 : /*---------------------------------------------------------------
72 : * ECSQ_quantize_vector()
73 : *
74 : *
75 : * ---------------------------------------------------------------*/
76 :
77 28041 : void ECSQ_quantize_vector(
78 : const float *input,
79 : const float global_gain,
80 : const int16_t N,
81 : int16_t *output )
82 : {
83 : int16_t i;
84 : float inv_global_gain;
85 : #ifdef DEBUGGING
86 : assert( N > 0 );
87 : assert( global_gain > 0.0f );
88 : #endif
89 :
90 28041 : inv_global_gain = 1.0f / global_gain;
91 1149681 : for ( i = 0; i < N; ++i )
92 : {
93 1121640 : output[i] = (int16_t) round_f( input[i] * inv_global_gain );
94 : }
95 :
96 28041 : return;
97 : }
98 :
99 : /*---------------------------------------------------------------
100 : * ECSQ_compute_optimal_gain()
101 : *
102 : * compute the optimal global gain for dequantization of output
103 : * if all the values in output are zero, it returns 0
104 : * ---------------------------------------------------------------*/
105 :
106 17070 : float ECSQ_compute_optimal_gain(
107 : const float *input,
108 : const int16_t N,
109 : const int16_t *output )
110 : {
111 : int16_t i;
112 : float sum_sq_output;
113 : float sum_input_output;
114 : float optimal_global_gain;
115 : #ifdef DEBUGGING
116 : assert( N > 0 );
117 : #endif
118 :
119 17070 : sum_sq_output = 0.0f;
120 17070 : sum_input_output = 0.0f;
121 699870 : for ( i = 0; i < N; ++i )
122 : {
123 682800 : sum_sq_output += (float) output[i] * (float) output[i];
124 682800 : sum_input_output += input[i] * (float) output[i];
125 : }
126 :
127 17070 : optimal_global_gain = 0.0f;
128 17070 : if ( sum_sq_output != 0.0f )
129 : {
130 16923 : optimal_global_gain = sum_input_output / sum_sq_output;
131 : }
132 :
133 17070 : return optimal_global_gain;
134 : }
135 :
136 : /*---------------------------------------------------------------
137 : * ECSQ_quantize_gain()
138 : *
139 : * quantize global gain
140 : * ---------------------------------------------------------------*/
141 :
142 33993 : static int16_t ECSQ_quantize_gain(
143 : float global_gain )
144 : {
145 : int16_t index;
146 :
147 : #ifdef DEBUGGING
148 : assert( global_gain > 0.0f );
149 : #endif
150 :
151 33993 : global_gain = max( global_gain, 1.0f ); /* because always index >= 0 anyway */
152 :
153 : /* min gain = 1 (index 0), max gain ~= 29145 (index 126), domain range ~= 90 dB, resolution 90 / 127 ~= 0.7 dB */
154 : /* value 127 (ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO) is reserved and indicates that all values in the vector are zero */
155 :
156 33993 : index = (int16_t) ( ECLVQ_GLOBAL_GAIN_FACTOR * log10f( global_gain ) + 0.4898f );
157 :
158 : /* for MSE quantization, the value f in (0, 1) is the middle between consecutive quantization points in the linear scale */
159 : /* 10 ^ (inv_global_gain_factor * f) - 1 = 10 ^ inv_global_gain_factor - 10 ^ (inv_global_gain_factor * f) */
160 : /* f = 0.5102, and when applying floor to convert to integer, 1 - f = 0.4898 must be used as the offset */
161 :
162 33993 : index = (int16_t) min( max( index, 0 ), 126 );
163 :
164 33993 : return index;
165 : }
166 :
167 : /*---------------------------------------------------------------
168 : * arith_encode_bit()
169 : *
170 : *
171 : * ---------------------------------------------------------------*/
172 :
173 460963 : static void arith_encode_bit(
174 : ECSQ_instance *ecsq_inst,
175 : const int16_t bit )
176 : {
177 : RangeUniEncState *rc_st_enc;
178 460963 : rc_st_enc = (RangeUniEncState *) ecsq_inst->ac_handle;
179 :
180 : #ifdef DEBUGGING
181 : assert( bit >= 0 );
182 : assert( bit < 2 );
183 : #endif
184 :
185 460963 : ecsq_inst->bit_count_estimate += 1024; /* 1024 eq 1 << 10, 22Q10 fixed-point representation */
186 :
187 460963 : if ( ecsq_inst->encoding_active )
188 : {
189 : /* call to the actual AC */
190 460963 : rc_uni_enc_encode_bits( rc_st_enc, bit, 1 );
191 : }
192 :
193 460963 : return;
194 : }
195 :
196 : /*---------------------------------------------------------------
197 : * arith_encode_bits()
198 : *
199 : *
200 : * ---------------------------------------------------------------*/
201 :
202 68482 : static void arith_encode_bits(
203 : ECSQ_instance *ecsq_inst,
204 : const uint16_t n,
205 : int16_t size )
206 : {
207 : RangeUniEncState *rc_st_enc;
208 68482 : rc_st_enc = (RangeUniEncState *) ecsq_inst->ac_handle;
209 :
210 : #ifdef DEBUGGING
211 : assert( n < ( 1 << size ) );
212 : #endif
213 :
214 68482 : ecsq_inst->bit_count_estimate += size << 10; /* 22Q10 fixed-point representation */
215 :
216 68482 : if ( ecsq_inst->encoding_active )
217 : {
218 68482 : rc_uni_enc_encode_bits( rc_st_enc, n, size );
219 : }
220 :
221 68482 : return;
222 : }
223 :
224 :
225 : /*---------------------------------------------------------------
226 : * code_length_from_count()
227 : *
228 : *
229 : * ---------------------------------------------------------------*/
230 :
231 1383483 : static int16_t code_length_from_count(
232 : const int16_t c )
233 : {
234 : /* compute the approximation of code length, 14 - log2(c), in 22Q10 fixed-point representation */
235 : /* with c in {1, ..., 2 ^ 14}, representing a probability count in 14-bit AC implementations */
236 : int16_t c_norm;
237 : int16_t res;
238 : #ifdef DEBUGGING
239 : assert( c >= 1 );
240 : assert( c <= ( 1 << 14 ) );
241 : #endif
242 :
243 : #define WMC_TOOL_SKIP
244 1383483 : c_norm = norm_s( (int16_t) c ); /* equivalent with 14 - floor(log_base2(c)) */
245 : #undef WMC_TOOL_SKIP
246 :
247 : /* compute linear approximation of log2(1 + x), for x in [0, 1], using a look-up table with 64 entries */
248 : /* normalize to {16384, ..., 32767}, subtract MSB bit, and convert to Q6 for indexing log2_1px_table */
249 1383483 : res = ( c_norm << 10 ) - log2_1px_table[( ( c << c_norm ) - ( 1 << 14 ) + ( 1 << 7 ) ) >> 8];
250 :
251 : #ifdef DEBUGGING
252 : assert( res >= 0 ); /* for c == 1 */
253 : assert( res <= 14 * ( 1 << 10 ) ); /* for c == 16384 */
254 : #endif
255 :
256 : /* |(14 - log2(c)) - res / (1 << 10)| < 0.0113, for c in {1, ..., 2 ^ 14} */
257 : /* complexity: 1 norm_s, 2 adds, 3 shifts, 1 table lookup */
258 1383483 : return res;
259 : }
260 :
261 : /*---------------------------------------------------------------
262 : * arith_encode_bit_prob()
263 : *
264 : * encoding for one bit with the probabilies prob_0 = count0 / 2 ^ ECSQ_PROB_BITS and prob_1 = 1 - prob_0
265 : * ---------------------------------------------------------------*/
266 :
267 55049 : static void arith_encode_bit_prob(
268 : ECSQ_instance *ecsq_inst,
269 : const int16_t count0,
270 : const int16_t bit )
271 : {
272 : int16_t count;
273 : RangeUniEncState *rc_st_enc;
274 55049 : rc_st_enc = (RangeUniEncState *) ecsq_inst->ac_handle;
275 :
276 : #ifdef DEBUGGING
277 : assert( bit >= 0 );
278 : assert( bit < 2 );
279 : assert( count0 >= 1 );
280 : assert( count0 <= ECSQ_PROB_TOTAL - 1 );
281 : #endif
282 :
283 55049 : count = ECSQ_PROB_TOTAL - count0;
284 :
285 55049 : if ( bit == 0 )
286 : {
287 36953 : count = count0;
288 : }
289 :
290 55049 : ecsq_inst->bit_count_estimate += code_length_from_count( count ); /* 22Q10 fixed-point representation */
291 :
292 55049 : if ( ecsq_inst->encoding_active )
293 : {
294 : /* call to the actual AC */
295 55049 : rc_uni_enc_encode_fast( rc_st_enc, bit * count0, count, 14 );
296 : }
297 :
298 55049 : return;
299 : }
300 :
301 : /*---------------------------------------------------------------
302 : * arith_encode_prob()
303 : *
304 : *
305 : * ---------------------------------------------------------------*/
306 :
307 657529 : static void arith_encode_prob(
308 : ECSQ_instance *ecsq_inst,
309 : const uint16_t table[],
310 : const int16_t table_size,
311 : const int16_t symbol )
312 : {
313 : int16_t count;
314 : RangeUniEncState *rc_st_enc;
315 :
316 657529 : rc_st_enc = (RangeUniEncState *) ecsq_inst->ac_handle;
317 :
318 : #ifdef DEBUGGING
319 : assert( symbol < table_size );
320 : assert( table[symbol] <= ( 1 << 14 ) );
321 : #else
322 657529 : count = table_size; /* just to avoid warning when DEBUGGING is deactivated */
323 : #endif
324 :
325 657529 : count = table[symbol] - table[symbol + 1];
326 : #ifdef DEBUGGING
327 : assert( count >= 1 );
328 : assert( count <= ( 1 << 14 ) );
329 : #endif
330 :
331 657529 : ecsq_inst->bit_count_estimate += code_length_from_count( count ); /* 22Q10 fixed-point representation */
332 :
333 657529 : if ( ecsq_inst->encoding_active )
334 : {
335 : /* call to the actual AC */
336 657529 : rc_uni_enc_encode_fast( rc_st_enc, ECSQ_PROB_TOTAL - table[symbol], count, 14 );
337 : }
338 :
339 657529 : return;
340 : }
341 :
342 : /*---------------------------------------------------------------
343 : * arith_encode_elias_mod()
344 : *
345 : *
346 : * ---------------------------------------------------------------*/
347 :
348 7870 : static void arith_encode_elias_mod(
349 : ECSQ_instance *ecsq_inst,
350 : const int16_t n )
351 : {
352 : int16_t i;
353 : #ifdef DEBUGGING
354 : assert( n >= 0 );
355 : /* n is already limited by the data type int16_t, so n_bits = floor(log_2(n)) <= 14 */
356 : #endif
357 :
358 7870 : if ( n <= 1 )
359 : {
360 : /* code for 0 is 10 and code for 1 is 11 */
361 2500 : arith_encode_bit( ecsq_inst, 1 );
362 2500 : arith_encode_bit( ecsq_inst, n );
363 : }
364 : else /* n >= 2 */
365 : {
366 : /* code consists of n_bits zero bits, an one bit, and n_bits data bits */
367 : int16_t n_bits;
368 :
369 : /* n_bits is floor(log_2(n)), the number of bits after the leading one bit */
370 5370 : n_bits = 30 - norm_l( n );
371 16149 : for ( i = 0; i < n_bits; i++ )
372 : {
373 10779 : arith_encode_bit( ecsq_inst, 0 );
374 : }
375 5370 : arith_encode_bit( ecsq_inst, 1 );
376 :
377 : /* encode the n_bits data bits at once */
378 5370 : arith_encode_bits( ecsq_inst, n - ( 1 << n_bits ), n_bits );
379 : }
380 :
381 7870 : return;
382 : }
383 :
384 : /*---------------------------------------------------------------
385 : * arith_encode_prob_escape()
386 : *
387 : *
388 : * ---------------------------------------------------------------*/
389 :
390 561512 : static void arith_encode_prob_escape(
391 : ECSQ_instance *ecsq_inst,
392 : const uint16_t table[],
393 : const int16_t table_size,
394 : const int16_t symbol )
395 : {
396 561512 : if ( symbol < table_size - 1 )
397 : {
398 553642 : arith_encode_prob( ecsq_inst, table, table_size, symbol );
399 : }
400 : else
401 : {
402 7870 : arith_encode_prob( ecsq_inst, table, table_size, table_size - 1 ); /* escape symbol */
403 : /* encode the additional value using a modified Elias integer code */
404 7870 : arith_encode_elias_mod( ecsq_inst, symbol - ( table_size - 1 ) );
405 : }
406 :
407 561512 : return;
408 : }
409 :
410 :
411 : /*---------------------------------------------------------------
412 : * get_best_param()
413 : *
414 : *
415 : * ---------------------------------------------------------------*/
416 :
417 223635 : static int16_t get_best_param(
418 : int16_t *x,
419 : const int16_t start_offset,
420 : const int16_t stop_offset,
421 : float *avg_abs_sum,
422 : int16_t *N0 )
423 : {
424 : int16_t v;
425 : int16_t val;
426 : int32_t sum_abs;
427 : int16_t count;
428 : int16_t count0;
429 : int16_t param;
430 :
431 223635 : const float offset = INV_LOG_2; /* offset = 1 / ln(2) and log2(offset) ~ 0.528766 */
432 :
433 223635 : sum_abs = 0;
434 223635 : count = stop_offset - start_offset + 1;
435 223635 : count0 = 0;
436 : #ifdef DEBUGGING
437 : assert( count > 0 );
438 : #endif
439 :
440 : /* compute sum(abs(x[v])) and sum(x[v] == 0) */
441 2012715 : for ( v = start_offset; v <= stop_offset; ++v )
442 : {
443 : #ifdef DEBUGGING
444 : assert( abs( x[v] ) <= MAX16B );
445 : #endif
446 :
447 1789080 : val = x[v];
448 1789080 : sum_abs += abs( val );
449 1789080 : if ( val == 0 )
450 : {
451 537408 : ++count0;
452 : }
453 : }
454 :
455 : #ifdef DEBUGGING
456 : assert( sum_abs <= count * MAX16B );
457 : #endif
458 :
459 : /* the vector has at most ECSQ_NONZERO_MAX values of +-1 and the rest are zeros */
460 223635 : if ( ( count - count0 <= ECSQ_NONZERO_MAX ) && ( sum_abs == count - count0 ) )
461 : {
462 30173 : *avg_abs_sum = ( sum_abs + 0.25f * count0 ) / count;
463 30173 : *N0 = count0;
464 :
465 30173 : return ECSQ_ALL_ZERO_PARAM;
466 : }
467 :
468 193462 : *avg_abs_sum = ( sum_abs + 0.25f * count0 ) / count;
469 193462 : *N0 = count0;
470 :
471 : /* the best Laplace integer parameter is floor(log2(avg_abs_sum) + log2(offset)) */
472 193462 : param = (int16_t) floor( log_base2( *avg_abs_sum * offset ) );
473 :
474 : /* limit param value to the available exponent range */
475 193462 : param = max( ECSQ_ALL_ZERO_PARAM + 1, param );
476 193462 : param = min( param, ECSQ_ALL_ZERO_PARAM + ECSQ_PARAM_COUNT - 1 );
477 :
478 193462 : return param;
479 : }
480 :
481 :
482 : /*---------------------------------------------------------------
483 : * get_est_size()
484 : *
485 : *
486 : * ---------------------------------------------------------------*/
487 :
488 : #define ECSQ_log2TB_FIRST_PARAM -2
489 :
490 670905 : static float get_est_size(
491 : const int16_t N,
492 : float avg_abs_sum,
493 : const int16_t N0,
494 : int16_t param )
495 : {
496 : float size;
497 : float two_to_param;
498 :
499 670905 : two_to_param = (float) ( 1 << abs( param ) );
500 670905 : if ( param < 0 )
501 : {
502 93825 : two_to_param = 1.0f / two_to_param;
503 : }
504 :
505 670905 : if ( param != ECSQ_ALL_ZERO_PARAM ) /* not all values are zeros */
506 : {
507 : int16_t index;
508 577080 : index = param - ECSQ_log2TB_FIRST_PARAM;
509 577080 : index = min( index, ECSQ_log2TB_SIZE - 2 );
510 :
511 : #ifdef DEBUGGING
512 : assert( index >= 0 );
513 : #endif
514 :
515 : /* the estimated size in bits is N * log2(2 * 2 ^ param) + */
516 : /* + N * log2(e) * (avg_abs_sum / 2 ^ param) - (N - N0) * log2(T(2 ^ param)) - */
517 : /* - N0 * log2(T(2 * 2 ^ param)) */
518 577080 : size = N * ( 1 + param + INV_LOG_2 * ( avg_abs_sum / two_to_param ) );
519 577080 : size -= ( N - N0 ) * log2TB[index];
520 577080 : size -= N0 * log2TB[index + 1];
521 : }
522 : else
523 : {
524 : /* used for all zero values or for very low entropy with number of nonzeros <= ECSQ_NONZERO_MAX */
525 : int16_t nonzero;
526 : float required_avg_abs_sum;
527 :
528 93825 : nonzero = N - N0;
529 :
530 93825 : required_avg_abs_sum = ( nonzero + 0.25f * N0 ) / N; /* the vector must have nonzero +-1 and N0 zeros */
531 :
532 93825 : if ( ( avg_abs_sum == required_avg_abs_sum ) && ( nonzero <= ECSQ_NONZERO_MAX ) )
533 : {
534 30173 : size = 2.0f; /* log_base2(1 + ECSQ_NONZERO_MAX), indicate the nonzero count */
535 :
536 : /* the number of bits for the nonzero mask is log2(nchoosek(N, nonzero)) */
537 30173 : size += ECSQ_log2_fact[N] - ECSQ_log2_fact[N - nonzero] - ECSQ_log2_fact[nonzero];
538 :
539 30173 : size += (float) nonzero; /* indicate the signs for nonzero values */
540 : }
541 : else
542 : {
543 : /* the method cannot be used, return a huge value so that it will never be chosen */
544 63652 : size = 1.0e11f;
545 : }
546 : }
547 :
548 670905 : return size;
549 : }
550 :
551 : /*---------------------------------------------------------------
552 : * ECSQ_encode_raw()
553 : *
554 : * encode input, which contains a concatenation of quantized RE8 integer-valued vectors;
555 : * the return value is the approximate number of bits written, expressed in 22Q10 fixed-point representation
556 : * ---------------------------------------------------------------*/
557 :
558 44727 : static int32_t ECSQ_encode_raw(
559 : ECSQ_instance *ecsq_inst,
560 : int16_t *input,
561 : const int16_t N )
562 : {
563 : int32_t bit_count_estimate_initial;
564 :
565 : float total_size;
566 : int16_t segment_count;
567 :
568 : int16_t seg_length, seg_start, seg_stop, segment, seg_count0;
569 : int32_t est_size;
570 :
571 : int16_t est_param, first_param, last_param, param;
572 : float best_size, test_size;
573 : int16_t best_param, best_params[ECSQ_VECTOR_SIZE_MAX / ECSQ_SEGMENT_SIZE];
574 : int16_t saved_seg_count0[ECSQ_VECTOR_SIZE_MAX / ECSQ_SEGMENT_SIZE];
575 :
576 : float avg_abs_sum;
577 44727 : const float scale_Q10 = 1.0f / 1024.0f;
578 : int16_t i, idx, shift, val, sym, nonzero, left0, left1, count, count0, lsbs;
579 : int16_t param_zb, best_param_zb; /* zero-based parameter index for coding */
580 : const uint16_t *tab_vals, *tab_abs_lsbs;
581 :
582 44727 : bit_count_estimate_initial = ecsq_inst->bit_count_estimate;
583 :
584 : #ifdef DEBUGGING
585 : assert( N > 0 );
586 : assert( ECSQ_ALL_ZERO_PARAM == -1 ); /* other values need code and table adjustments */
587 : assert( ( ecsq_inst->config_index >= 1 ) && ( ecsq_inst->config_index < ECSQ_CONFIG_COUNT ) );
588 :
589 : /* ensure we are using target SNR configurations, disable target bits configurations for the moment */
590 : assert( ( ecsq_inst->config_index == 1 ) || ( ecsq_inst->config_index == 3 ) || ( ecsq_inst->config_index == 5 ) );
591 : #endif
592 :
593 44727 : total_size = 0.0f;
594 44727 : segment_count = ( N + ECSQ_SEGMENT_SIZE - 1 ) / ECSQ_SEGMENT_SIZE;
595 :
596 268362 : for ( segment = 0; segment < segment_count; ++segment )
597 : {
598 223635 : seg_start = segment * ECSQ_SEGMENT_SIZE;
599 223635 : seg_stop = min( seg_start + ECSQ_SEGMENT_SIZE, N ) - 1;
600 223635 : seg_length = seg_stop - seg_start + 1;
601 :
602 223635 : est_param = get_best_param( input, seg_start, seg_stop, &avg_abs_sum, &seg_count0 );
603 223635 : saved_seg_count0[segment] = seg_count0;
604 :
605 : /* find the best param around est_param for the current segment count */
606 223635 : best_size = 1.0e10f;
607 223635 : best_param = -1000;
608 :
609 223635 : if ( est_param == ECSQ_ALL_ZERO_PARAM ) /* all values are zero */
610 : {
611 30173 : first_param = ECSQ_ALL_ZERO_PARAM;
612 30173 : last_param = ECSQ_ALL_ZERO_PARAM + 2 * ECSQ_PARAM_SEARCH_RANGE;
613 : }
614 : else
615 : {
616 193462 : first_param = max( ECSQ_ALL_ZERO_PARAM, est_param - ECSQ_PARAM_SEARCH_RANGE );
617 193462 : last_param = min( est_param + ECSQ_PARAM_SEARCH_RANGE, ECSQ_ALL_ZERO_PARAM + ECSQ_PARAM_COUNT - 1 );
618 : }
619 :
620 894540 : for ( param = first_param; param <= last_param; ++param )
621 : {
622 670905 : param_zb = param - ECSQ_ALL_ZERO_PARAM;
623 670905 : count = ECSQ_tab_param[ecsq_inst->config_index][param_zb] - ECSQ_tab_param[ecsq_inst->config_index][param_zb + 1];
624 670905 : test_size = scale_Q10 * code_length_from_count( count );
625 :
626 670905 : test_size += get_est_size( seg_length, avg_abs_sum, seg_count0, param );
627 :
628 670905 : if ( test_size < best_size )
629 : {
630 295691 : best_param = param;
631 295691 : best_size = test_size;
632 : }
633 : }
634 :
635 223635 : best_params[segment] = best_param;
636 223635 : total_size += best_size;
637 : }
638 :
639 44727 : if ( !ecsq_inst->encoding_active ) /* only size estimation is needed */
640 : {
641 27804 : est_size = (int32_t) ( total_size * 1024.0 + 0.5 ); /* 22Q10 fixed-point representation */
642 :
643 27804 : return est_size;
644 : }
645 :
646 : /* encode with the best parameters: best_params[] */
647 101538 : for ( segment = 0; segment < segment_count; ++segment )
648 : {
649 84615 : seg_start = segment * ECSQ_SEGMENT_SIZE;
650 84615 : seg_stop = seg_start + ECSQ_SEGMENT_SIZE - 1;
651 84615 : seg_length = ECSQ_SEGMENT_SIZE;
652 84615 : if ( segment == segment_count - 1 )
653 : {
654 16923 : seg_stop = N - 1;
655 16923 : seg_length = seg_stop - seg_start + 1;
656 : }
657 :
658 84615 : best_param_zb = best_params[segment] - ECSQ_ALL_ZERO_PARAM;
659 84615 : shift = max( 0, best_param_zb - 3 ); /* first nonzero shift of 1 is used for param 3 */
660 :
661 84615 : arith_encode_prob( ecsq_inst, ECSQ_tab_param[ecsq_inst->config_index], ECSQ_PARAM_COUNT, best_param_zb );
662 :
663 : /* encode the actual values if not using the ECSQ_ALL_ZERO_PARAM parameter */
664 84615 : if ( best_param_zb != 0 )
665 : {
666 70189 : tab_vals = ECSQ_tab_vals[best_param_zb - 1];
667 70189 : idx = min( shift, 4 );
668 70189 : tab_abs_lsbs = ECSQ_tab_abs_lsbs[idx];
669 :
670 631701 : for ( i = seg_start; i <= seg_stop; ++i )
671 : {
672 561512 : val = input[i];
673 561512 : sym = (int16_t) abs( val );
674 :
675 561512 : if ( shift != 0 )
676 : {
677 60088 : lsbs = sym & ( ( 1 << shift ) - 1 );
678 60088 : sym = sym >> shift;
679 :
680 60088 : arith_encode_prob_escape( ecsq_inst, tab_vals, ECSQ_TAB_VALS_SIZE, sym );
681 :
682 60088 : if ( ( sym > 0 ) || ( shift > 4 ) )
683 : {
684 48686 : arith_encode_bits( ecsq_inst, lsbs, shift );
685 : }
686 : else /* (sym == 0) && (shift <= 4) */
687 : {
688 11402 : arith_encode_prob( ecsq_inst, tab_abs_lsbs, 1 << shift, lsbs );
689 : }
690 : }
691 : else /* shift == 0 */
692 : {
693 501424 : arith_encode_prob_escape( ecsq_inst, tab_vals, ECSQ_TAB_VALS_SIZE, sym );
694 : }
695 :
696 561512 : if ( val != 0 )
697 : {
698 418619 : arith_encode_bit( ecsq_inst, get_sign( val ) );
699 : }
700 : }
701 : }
702 : else
703 : {
704 14426 : nonzero = seg_length - saved_seg_count0[segment];
705 :
706 : #ifdef DEBUGGING
707 : assert( ECSQ_NONZERO_MAX == 3 );
708 : assert( nonzero <= ECSQ_NONZERO_MAX );
709 : #endif
710 :
711 14426 : arith_encode_bits( ecsq_inst, nonzero, 2 ); /* log_base2(ECSQ_NONZERO_MAX + 1) == 2 */
712 :
713 14426 : left1 = nonzero;
714 14426 : left0 = seg_length - nonzero;
715 :
716 129834 : for ( i = seg_start; i <= seg_stop; ++i )
717 : {
718 115408 : val = input[i];
719 115408 : sym = (int16_t) abs( val );
720 :
721 : #ifdef DEBUGGING
722 : assert( sym <= 1 );
723 : #endif
724 :
725 115408 : if ( left1 == 0 )
726 : {
727 : #ifdef DEBUGGING
728 : assert( sym == 0 );
729 : #endif
730 : }
731 58148 : else if ( left0 == 0 )
732 : {
733 : #ifdef DEBUGGING
734 : assert( sym == 1 );
735 : #endif
736 : }
737 : else
738 : {
739 55049 : count0 = left0 * ECSQ_tab_inverse[left0 + left1]; /* left0 * round(ECSQ_PROB_TOTAL / (left0 + left1)) */
740 55049 : arith_encode_bit_prob( ecsq_inst, count0, sym );
741 : }
742 :
743 115408 : if ( sym != 0 )
744 : {
745 21195 : arith_encode_bit( ecsq_inst, get_sign( val ) );
746 21195 : --left1;
747 : }
748 : else
749 : {
750 94213 : --left0;
751 : }
752 : }
753 : }
754 : }
755 :
756 : #ifdef DEBUGGING
757 : DEBUG_LINE( 1 )
758 : {
759 : static FILE *tolf = NULL;
760 : if ( tolf == NULL )
761 : {
762 : tolf = fopen( "tolerance.txt", "wt" );
763 : }
764 : fprintf( tolf, "%8.3f %8.3f\n", ( ecsq_inst->bit_count_estimate - bit_count_estimate_initial ) / 1024.0, ( ecsq_inst->bit_count_estimate - bit_count_estimate_initial ) / 1024.0 - total_size );
765 : fflush( tolf );
766 : }
767 : #endif
768 :
769 16923 : return ecsq_inst->bit_count_estimate - bit_count_estimate_initial;
770 : }
771 :
772 :
773 : /*---------------------------------------------------------------
774 : * ECSQ_encode_target_SNR()
775 : *
776 : * encode input with an approximate target of target_SNR signal-to-noise ratio, and ensure no more than max_bits are used;
777 : * the computed global gain index is returned into global_gain_index_output;
778 : * if global_gain_index_output == ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO, nothing is written and the function returns 0;
779 : * if output pointer is not NULL, it will contain the dequantized vector, as it will be available at the decoder side;
780 : * the return value is the approximate number of bits written, expressed in 22Q10 fixed-point representation
781 : * ---------------------------------------------------------------*/
782 :
783 : #define ECSQ_MAX_BITS_ITERATIONS 2
784 :
785 17398 : int32_t ECSQ_encode_target_SNR(
786 : ECSQ_instance *ecsq_inst,
787 : const float *input,
788 : const int16_t N,
789 : const float target_SNR,
790 : const int16_t max_bits,
791 : float *output,
792 : int16_t *global_gain_index_output )
793 : {
794 : int16_t global_gain_index;
795 : int16_t global_gain_index_last; /* used to potentially save one call to ECSQ_quantize_vector */
796 : int16_t quantized_input[ECSQ_VECTOR_SIZE_MAX];
797 : int16_t saved_encoding_active;
798 : int32_t saved_bit_count_estimate;
799 : int32_t test_size, adjust_size;
800 : int16_t i, iteration;
801 : float global_gain, adjust_global_gain_index;
802 : int32_t max_bits_fixpt;
803 : float sum_squared, target_ratio, target_sum_squared_error;
804 17398 : const float global_gain_step = powf( 10.0f, ECLVQ_INV_GLOBAL_GAIN_FACTOR );
805 : #ifdef DEBUGGING
806 : int16_t j;
807 : assert( N > 0 );
808 : #endif
809 :
810 17398 : max_bits_fixpt = max_bits * 1024; /* max_bits_fixpt is in 22Q10 fixed-point representation */
811 :
812 17398 : if ( target_SNR <= 0.0f )
813 : {
814 : /* a target SNR of 0.0 dB is already achieved by quantizing all values in the vector to zero */
815 0 : *global_gain_index_output = ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO;
816 0 : if ( output != NULL )
817 : {
818 0 : set_f( output, 0.0f, N );
819 : }
820 :
821 0 : return 0; /* nothing is coded when global gain index is ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO */
822 : }
823 :
824 17398 : sum_squared = 0.0f;
825 713318 : for ( i = 0; i < N; ++i )
826 : {
827 695920 : sum_squared += input[i] * input[i];
828 : }
829 :
830 17398 : if ( sum_squared < 0.25f ) /* all the values in the input vector will always be quantized to zero */
831 : {
832 : /* the condition above holds because sum(input[i] ^ 2) < 0.25 => max(abs(input[i])) < 0.5 */
833 328 : *global_gain_index_output = ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO;
834 328 : if ( output != NULL )
835 : {
836 0 : set_f( output, 0.0f, N );
837 : }
838 :
839 328 : return 0; /* nothing is coded when global gain index is ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO */
840 : }
841 :
842 : /* save internal state and activate size evaluation only */
843 17070 : saved_encoding_active = ecsq_inst->encoding_active;
844 17070 : saved_bit_count_estimate = ecsq_inst->bit_count_estimate;
845 17070 : ecsq_inst->encoding_active = 0;
846 :
847 : /* target_ratio is the target ratio between the sum squared values of input and sum squared values of quantization error */
848 17070 : target_ratio = powf( 10.0f, target_SNR / 10.0f );
849 17070 : target_sum_squared_error = sum_squared / target_ratio;
850 : /* the mean of squared quantization error for uniform scalar quantization is 1 / 12, approximately 0.0833 */
851 : /* when including global_gain, the relationship is target_sum_squared_error ~ (0.0833 * N) * global_gain ^ 2 */
852 : /* the representable range for global_gain is from 1 (global_gain_index 0) to 29145 (global_gain_index 126) inclusive */
853 17070 : global_gain = sqrtf( target_sum_squared_error / ( 0.0833f * (float) N ) );
854 : /* quantize the estimated global_gain */
855 17070 : global_gain_index = ECSQ_quantize_gain( global_gain );
856 :
857 17070 : iteration = 0;
858 :
859 : /* do the quantization with the dequantized estimated global_gain_index found */
860 17070 : global_gain = ECSQ_dequantize_gain( global_gain_index );
861 17070 : global_gain_index_last = global_gain_index;
862 17070 : ECSQ_quantize_vector( input, global_gain, N, quantized_input );
863 :
864 17070 : test_size = ECSQ_encode_raw( ecsq_inst, quantized_input, N );
865 : #ifdef DEBUGGING
866 : DEBUG_LINE( 1 )
867 : printf( "global_gain_index[0] %3d global_gain %9.3f test_size %9d max_bits %9d\n", global_gain_index, global_gain, test_size, max_bits_fixpt );
868 : #endif
869 :
870 17070 : ++iteration;
871 27804 : while ( ( test_size > max_bits_fixpt ) && ( iteration < ECSQ_MAX_BITS_ITERATIONS ) )
872 : {
873 10734 : adjust_size = test_size - max_bits_fixpt;
874 : /* assume doubling the quantization step size will reduce the entropy with (up to) one bit */
875 10734 : adjust_global_gain_index = (int16_t) ceil( adjust_size / ( 1024.0f * N * log_base2( global_gain_step ) ) );
876 10734 : global_gain_index = min( (int16_t) ( global_gain_index + adjust_global_gain_index ), 126 );
877 :
878 10734 : global_gain = ECSQ_dequantize_gain( global_gain_index );
879 10734 : global_gain_index_last = global_gain_index;
880 10734 : ECSQ_quantize_vector( input, global_gain, N, quantized_input );
881 :
882 10734 : test_size = ECSQ_encode_raw( ecsq_inst, quantized_input, N );
883 : #ifdef DEBUGGING
884 : DEBUG_LINE( 1 )
885 : printf( "global_gain_index[%d] %3d global_gain %9.3f test_size %9d max_bits %9d\n", iteration, global_gain_index, global_gain, test_size, max_bits_fixpt );
886 : #endif
887 :
888 10734 : ++iteration;
889 : }
890 :
891 17070 : if ( test_size > max_bits_fixpt )
892 : {
893 : #ifdef DEBUGGING
894 : DEBUG_LINE( 1 )
895 : printf( "test_size %9d still larger than max_bits %9d, incrementing global_gain_index\n", test_size, max_bits_fixpt );
896 : #endif
897 : /* further increase the quantization step with the smallest increment for global_gain_index */
898 237 : global_gain_index = (int16_t) min( global_gain_index + 1, 126 );
899 : }
900 :
901 : /* restore internal state */
902 17070 : ecsq_inst->encoding_active = saved_encoding_active;
903 17070 : ecsq_inst->bit_count_estimate = saved_bit_count_estimate;
904 :
905 : /* do the quantization with the dequantized final global_gain_index found */
906 17070 : global_gain = ECSQ_dequantize_gain( global_gain_index );
907 :
908 17070 : if ( global_gain_index != global_gain_index_last )
909 : {
910 237 : ECSQ_quantize_vector( input, global_gain, N, quantized_input );
911 : }
912 :
913 17070 : global_gain = ECSQ_compute_optimal_gain( input, N, quantized_input );
914 :
915 17070 : if ( global_gain == 0.0f ) /* all values in quantized_input are zero */
916 : {
917 147 : *global_gain_index_output = ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO;
918 147 : if ( output != NULL )
919 : {
920 0 : set_f( output, 0.0f, N );
921 : }
922 :
923 147 : return 0; /* nothing is coded when global gain index is ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO */
924 : }
925 :
926 16923 : global_gain_index = ECSQ_quantize_gain( global_gain );
927 16923 : *global_gain_index_output = global_gain_index;
928 :
929 : #ifdef DEBUGGING
930 : DEBUG_LINE( 1 )
931 : {
932 : float actual_sum_squared_error;
933 : float delta_global_gain_index;
934 : actual_sum_squared_error = 0.0f;
935 :
936 : /* compute the actual sum squared quantization error */
937 : global_gain = ECSQ_dequantize_gain( global_gain_index );
938 : for ( j = 0; j < N; ++j )
939 : {
940 : float error;
941 : error = input[j] - (float) quantized_input[j] * global_gain;
942 :
943 : actual_sum_squared_error += error * error;
944 : }
945 : delta_global_gain_index = (float) ( log( target_sum_squared_error / actual_sum_squared_error ) / ( 2.0f * log( global_gain_step ) ) );
946 : printf( "global_gain_index %3d global_gain %9.3f target_SSE %13.6e actual_SSE %13.6e delta_global_gain_index %9.3f\n", global_gain_index, global_gain, target_sum_squared_error, actual_sum_squared_error, delta_global_gain_index );
947 : }
948 : #endif
949 :
950 16923 : if ( output != NULL )
951 : {
952 0 : global_gain = ECSQ_dequantize_gain( global_gain_index );
953 0 : ECSQ_dequantize_vector( quantized_input, global_gain, N, output );
954 : }
955 :
956 16923 : ECSQ_encode_raw( ecsq_inst, quantized_input, N );
957 :
958 16923 : return ecsq_inst->bit_count_estimate - saved_bit_count_estimate;
959 : }
|