LCOV - code coverage report
Current view: top level - lib_enc - ivas_stereo_eclvq_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 6baab0c613aa6c7100498ed7b93676aa8198a493 Lines: 235 243 96.7 %
Date: 2025-05-28 04:28:20 Functions: 16 16 100.0 %

          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     2503089 : static double log_base2(
      54             :     double x )
      55             : {
      56     2503089 :     return log( x ) * INV_LOG_2;
      57             : }
      58             : 
      59             : /*---------------------------------------------------------------
      60             :  * get_sign()
      61             :  *
      62             :  *
      63             :  * ---------------------------------------------------------------*/
      64             : 
      65     5688469 : static int16_t get_sign( int16_t n )
      66             : {
      67     5688469 :     return (uint16_t) n >> 15; /* extract the sign bit */
      68             : }
      69             : 
      70             : 
      71             : /*---------------------------------------------------------------
      72             :  * ECSQ_quantize_vector()
      73             :  *
      74             :  *
      75             :  * ---------------------------------------------------------------*/
      76             : 
      77      340352 : 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      340352 :     inv_global_gain = 1.0f / global_gain;
      91    13954432 :     for ( i = 0; i < N; ++i )
      92             :     {
      93    13614080 :         output[i] = (int16_t) round_f( input[i] * inv_global_gain );
      94             :     }
      95             : 
      96      340352 :     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      228173 : 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      228173 :     sum_sq_output = 0.0f;
     120      228173 :     sum_input_output = 0.0f;
     121     9355093 :     for ( i = 0; i < N; ++i )
     122             :     {
     123     9126920 :         sum_sq_output += (float) output[i] * (float) output[i];
     124     9126920 :         sum_input_output += input[i] * (float) output[i];
     125             :     }
     126             : 
     127      228173 :     optimal_global_gain = 0.0f;
     128      228173 :     if ( sum_sq_output != 0.0f )
     129             :     {
     130      226979 :         optimal_global_gain = sum_input_output / sum_sq_output;
     131             :     }
     132             : 
     133      228173 :     return optimal_global_gain;
     134             : }
     135             : 
     136             : /*---------------------------------------------------------------
     137             :  * ECSQ_quantize_gain()
     138             :  *
     139             :  * quantize global gain
     140             :  * ---------------------------------------------------------------*/
     141             : 
     142      455152 : 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      455152 :     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      455152 :     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      455152 :     index = (int16_t) min( max( index, 0 ), 126 );
     163             : 
     164      455152 :     return index;
     165             : }
     166             : 
     167             : /*---------------------------------------------------------------
     168             :  * arith_encode_bit()
     169             :  *
     170             :  *
     171             :  * ---------------------------------------------------------------*/
     172             : 
     173     5888768 : static void arith_encode_bit(
     174             :     ECSQ_instance *ecsq_inst,
     175             :     const int16_t bit )
     176             : {
     177             :     RangeUniEncState *rc_st_enc;
     178     5888768 :     rc_st_enc = (RangeUniEncState *) ecsq_inst->ac_handle;
     179             : 
     180             : #ifdef DEBUGGING
     181             :     assert( bit >= 0 );
     182             :     assert( bit < 2 );
     183             : #endif
     184             : 
     185     5888768 :     ecsq_inst->bit_count_estimate += 1024; /* 1024 eq 1 << 10, 22Q10 fixed-point representation */
     186             : 
     187     5888768 :     if ( ecsq_inst->encoding_active )
     188             :     {
     189             :         /* call to the actual AC */
     190     5888768 :         rc_uni_enc_encode_bits( rc_st_enc, bit, 1 );
     191             :     }
     192             : 
     193     5888768 :     return;
     194             : }
     195             : 
     196             : /*---------------------------------------------------------------
     197             :  * arith_encode_bits()
     198             :  *
     199             :  *
     200             :  * ---------------------------------------------------------------*/
     201             : 
     202      663314 : 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      663314 :     rc_st_enc = (RangeUniEncState *) ecsq_inst->ac_handle;
     209             : 
     210             : #ifdef DEBUGGING
     211             :     assert( n < ( 1 << size ) );
     212             : #endif
     213             : 
     214      663314 :     ecsq_inst->bit_count_estimate += size << 10; /* 22Q10 fixed-point representation */
     215             : 
     216      663314 :     if ( ecsq_inst->encoding_active )
     217             :     {
     218      663314 :         rc_uni_enc_encode_bits( rc_st_enc, n, size );
     219             :     }
     220             : 
     221      663314 :     return;
     222             : }
     223             : 
     224             : 
     225             : /*---------------------------------------------------------------
     226             :  * code_length_from_count()
     227             :  *
     228             :  *
     229             :  * ---------------------------------------------------------------*/
     230             : 
     231    17760528 : 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    17760528 :     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    17760528 :     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    17760528 :     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      643096 : 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      643096 :     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      643096 :     count = ECSQ_PROB_TOTAL - count0;
     284             : 
     285      643096 :     if ( bit == 0 )
     286             :     {
     287      437586 :         count = count0;
     288             :     }
     289             : 
     290      643096 :     ecsq_inst->bit_count_estimate += code_length_from_count( count ); /* 22Q10 fixed-point representation */
     291             : 
     292      643096 :     if ( ecsq_inst->encoding_active )
     293             :     {
     294             :         /* call to the actual AC */
     295      643096 :         rc_uni_enc_encode_fast( rc_st_enc, bit * count0, count, 14 );
     296             :     }
     297             : 
     298      643096 :     return;
     299             : }
     300             : 
     301             : /*---------------------------------------------------------------
     302             :  * arith_encode_prob()
     303             :  *
     304             :  *
     305             :  * ---------------------------------------------------------------*/
     306             : 
     307     8639372 : 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     8639372 :     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     8639372 :     count = table_size; /* just to avoid warning when DEBUGGING is deactivated */
     323             : #endif
     324             : 
     325     8639372 :     count = table[symbol] - table[symbol + 1];
     326             : #ifdef DEBUGGING
     327             :     assert( count >= 1 );
     328             :     assert( count <= ( 1 << 14 ) );
     329             : #endif
     330             : 
     331     8639372 :     ecsq_inst->bit_count_estimate += code_length_from_count( count ); /* 22Q10 fixed-point representation */
     332             : 
     333     8639372 :     if ( ecsq_inst->encoding_active )
     334             :     {
     335             :         /* call to the actual AC */
     336     8639372 :         rc_uni_enc_encode_fast( rc_st_enc, ECSQ_PROB_TOTAL - table[symbol], count, 14 );
     337             :     }
     338             : 
     339     8639372 :     return;
     340             : }
     341             : 
     342             : /*---------------------------------------------------------------
     343             :  * arith_encode_elias_mod()
     344             :  *
     345             :  *
     346             :  * ---------------------------------------------------------------*/
     347             : 
     348       75946 : 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       75946 :     if ( n <= 1 )
     359             :     {
     360             :         /* code for 0 is 10 and code for 1 is 11 */
     361       26090 :         arith_encode_bit( ecsq_inst, 1 );
     362       26090 :         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       49856 :         n_bits = 30 - norm_l( n );
     371      148119 :         for ( i = 0; i < n_bits; i++ )
     372             :         {
     373       98263 :             arith_encode_bit( ecsq_inst, 0 );
     374             :         }
     375       49856 :         arith_encode_bit( ecsq_inst, 1 );
     376             : 
     377             :         /* encode the n_bits data bits at once */
     378       49856 :         arith_encode_bits( ecsq_inst, n - ( 1 << n_bits ), n_bits );
     379             :     }
     380             : 
     381       75946 :     return;
     382             : }
     383             : 
     384             : /*---------------------------------------------------------------
     385             :  * arith_encode_prob_escape()
     386             :  *
     387             :  *
     388             :  * ---------------------------------------------------------------*/
     389             : 
     390     7394816 : 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     7394816 :     if ( symbol < table_size - 1 )
     397             :     {
     398     7318870 :         arith_encode_prob( ecsq_inst, table, table_size, symbol );
     399             :     }
     400             :     else
     401             :     {
     402       75946 :         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       75946 :         arith_encode_elias_mod( ecsq_inst, symbol - ( table_size - 1 ) );
     405             :     }
     406             : 
     407     7394816 :     return;
     408             : }
     409             : 
     410             : 
     411             : /*---------------------------------------------------------------
     412             :  * get_best_param()
     413             :  *
     414             :  *
     415             :  * ---------------------------------------------------------------*/
     416             : 
     417     2826020 : 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     2826020 :     const float offset = INV_LOG_2; /* offset = 1 / ln(2) and log2(offset) ~ 0.528766 */
     432             : 
     433     2826020 :     sum_abs = 0;
     434     2826020 :     count = stop_offset - start_offset + 1;
     435     2826020 :     count0 = 0;
     436             : #ifdef DEBUGGING
     437             :     assert( count > 0 );
     438             : #endif
     439             : 
     440             :     /* compute sum(abs(x[v])) and sum(x[v] == 0) */
     441    25434180 :     for ( v = start_offset; v <= stop_offset; ++v )
     442             :     {
     443             : #ifdef DEBUGGING
     444             :         assert( abs( x[v] ) <= MAX16B );
     445             : #endif
     446             : 
     447    22608160 :         val = x[v];
     448    22608160 :         sum_abs += abs( val );
     449    22608160 :         if ( val == 0 )
     450             :         {
     451     7392058 :             ++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     2826020 :     if ( ( count - count0 <= ECSQ_NONZERO_MAX ) && ( sum_abs == count - count0 ) )
     461             :     {
     462      432983 :         *avg_abs_sum = ( sum_abs + 0.25f * count0 ) / count;
     463      432983 :         *N0 = count0;
     464             : 
     465      432983 :         return ECSQ_ALL_ZERO_PARAM;
     466             :     }
     467             : 
     468     2393037 :     *avg_abs_sum = ( sum_abs + 0.25f * count0 ) / count;
     469     2393037 :     *N0 = count0;
     470             : 
     471             :     /* the best Laplace integer parameter is floor(log2(avg_abs_sum) + log2(offset)) */
     472     2393037 :     param = (int16_t) floor( log_base2( *avg_abs_sum * offset ) );
     473             : 
     474             :     /* limit param value to the available exponent range */
     475     2393037 :     param = max( ECSQ_ALL_ZERO_PARAM + 1, param );
     476     2393037 :     param = min( param, ECSQ_ALL_ZERO_PARAM + ECSQ_PARAM_COUNT - 1 );
     477             : 
     478     2393037 :     return param;
     479             : }
     480             : 
     481             : 
     482             : /*---------------------------------------------------------------
     483             :  * get_est_size()
     484             :  *
     485             :  *
     486             :  * ---------------------------------------------------------------*/
     487             : 
     488             : #define ECSQ_log2TB_FIRST_PARAM -2
     489             : 
     490     8478060 : 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     8478060 :     two_to_param = (float) ( 1 << abs( param ) );
     500     8478060 :     if ( param < 0 )
     501             :     {
     502     1240043 :         two_to_param = 1.0f / two_to_param;
     503             :     }
     504             : 
     505     8478060 :     if ( param != ECSQ_ALL_ZERO_PARAM ) /* not all values are zeros */
     506             :     {
     507             :         int16_t index;
     508     7238017 :         index = param - ECSQ_log2TB_FIRST_PARAM;
     509     7238017 :         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     7238017 :         size = N * ( 1 + param + INV_LOG_2 * ( avg_abs_sum / two_to_param ) );
     519     7238017 :         size -= ( N - N0 ) * log2TB[index];
     520     7238017 :         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     1240043 :         nonzero = N - N0;
     529             : 
     530     1240043 :         required_avg_abs_sum = ( nonzero + 0.25f * N0 ) / N; /* the vector must have nonzero +-1 and N0 zeros */
     531             : 
     532     1240043 :         if ( ( avg_abs_sum == required_avg_abs_sum ) && ( nonzero <= ECSQ_NONZERO_MAX ) )
     533             :         {
     534      432983 :             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      432983 :             size += ECSQ_log2_fact[N] - ECSQ_log2_fact[N - nonzero] - ECSQ_log2_fact[nonzero];
     538             : 
     539      432983 :             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      807060 :             size = 1.0e11f;
     545             :         }
     546             :     }
     547             : 
     548     8478060 :     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      565204 : 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      565204 :     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      565204 :     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      565204 :     total_size = 0.0f;
     594      565204 :     segment_count = ( N + ECSQ_SEGMENT_SIZE - 1 ) / ECSQ_SEGMENT_SIZE;
     595             : 
     596     3391224 :     for ( segment = 0; segment < segment_count; ++segment )
     597             :     {
     598     2826020 :         seg_start = segment * ECSQ_SEGMENT_SIZE;
     599     2826020 :         seg_stop = min( seg_start + ECSQ_SEGMENT_SIZE, N ) - 1;
     600     2826020 :         seg_length = seg_stop - seg_start + 1;
     601             : 
     602     2826020 :         est_param = get_best_param( input, seg_start, seg_stop, &avg_abs_sum, &seg_count0 );
     603     2826020 :         saved_seg_count0[segment] = seg_count0;
     604             : 
     605             :         /* find the best param around est_param for the current segment count */
     606     2826020 :         best_size = 1.0e10f;
     607     2826020 :         best_param = -1000;
     608             : 
     609     2826020 :         if ( est_param == ECSQ_ALL_ZERO_PARAM ) /* all values are zero */
     610             :         {
     611      432983 :             first_param = ECSQ_ALL_ZERO_PARAM;
     612      432983 :             last_param = ECSQ_ALL_ZERO_PARAM + 2 * ECSQ_PARAM_SEARCH_RANGE;
     613             :         }
     614             :         else
     615             :         {
     616     2393037 :             first_param = max( ECSQ_ALL_ZERO_PARAM, est_param - ECSQ_PARAM_SEARCH_RANGE );
     617     2393037 :             last_param = min( est_param + ECSQ_PARAM_SEARCH_RANGE, ECSQ_ALL_ZERO_PARAM + ECSQ_PARAM_COUNT - 1 );
     618             :         }
     619             : 
     620    11304080 :         for ( param = first_param; param <= last_param; ++param )
     621             :         {
     622     8478060 :             param_zb = param - ECSQ_ALL_ZERO_PARAM;
     623     8478060 :             count = ECSQ_tab_param[ecsq_inst->config_index][param_zb] - ECSQ_tab_param[ecsq_inst->config_index][param_zb + 1];
     624     8478060 :             test_size = scale_Q10 * code_length_from_count( count );
     625             : 
     626     8478060 :             test_size += get_est_size( seg_length, avg_abs_sum, seg_count0, param );
     627             : 
     628     8478060 :             if ( test_size < best_size )
     629             :             {
     630     3644673 :                 best_param = param;
     631     3644673 :                 best_size = test_size;
     632             :             }
     633             :         }
     634             : 
     635     2826020 :         best_params[segment] = best_param;
     636     2826020 :         total_size += best_size;
     637             :     }
     638             : 
     639      565204 :     if ( !ecsq_inst->encoding_active ) /* only size estimation is needed */
     640             :     {
     641      338225 :         est_size = (int32_t) ( total_size * 1024.0 + 0.5 ); /* 22Q10 fixed-point representation */
     642             : 
     643      338225 :         return est_size;
     644             :     }
     645             : 
     646             :     /* encode with the best parameters: best_params[] */
     647     1361874 :     for ( segment = 0; segment < segment_count; ++segment )
     648             :     {
     649     1134895 :         seg_start = segment * ECSQ_SEGMENT_SIZE;
     650     1134895 :         seg_stop = seg_start + ECSQ_SEGMENT_SIZE - 1;
     651     1134895 :         seg_length = ECSQ_SEGMENT_SIZE;
     652     1134895 :         if ( segment == segment_count - 1 )
     653             :         {
     654      226979 :             seg_stop = N - 1;
     655      226979 :             seg_length = seg_stop - seg_start + 1;
     656             :         }
     657             : 
     658     1134895 :         best_param_zb = best_params[segment] - ECSQ_ALL_ZERO_PARAM;
     659     1134895 :         shift = max( 0, best_param_zb - 3 ); /* first nonzero shift of 1 is used for param 3 */
     660             : 
     661     1134895 :         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     1134895 :         if ( best_param_zb != 0 )
     665             :         {
     666      924352 :             tab_vals = ECSQ_tab_vals[best_param_zb - 1];
     667      924352 :             idx = min( shift, 4 );
     668      924352 :             tab_abs_lsbs = ECSQ_tab_abs_lsbs[idx];
     669             : 
     670     8319168 :             for ( i = seg_start; i <= seg_stop; ++i )
     671             :             {
     672     7394816 :                 val = input[i];
     673     7394816 :                 sym = (int16_t) abs( val );
     674             : 
     675     7394816 :                 if ( shift != 0 )
     676             :                 {
     677      512576 :                     lsbs = sym & ( ( 1 << shift ) - 1 );
     678      512576 :                     sym = sym >> shift;
     679             : 
     680      512576 :                     arith_encode_prob_escape( ecsq_inst, tab_vals, ECSQ_TAB_VALS_SIZE, sym );
     681             : 
     682      512576 :                     if ( ( sym > 0 ) || ( shift > 4 ) )
     683             :                     {
     684      402915 :                         arith_encode_bits( ecsq_inst, lsbs, shift );
     685             :                     }
     686             :                     else /* (sym == 0) && (shift <= 4) */
     687             :                     {
     688      109661 :                         arith_encode_prob( ecsq_inst, tab_abs_lsbs, 1 << shift, lsbs );
     689             :                     }
     690             :                 }
     691             :                 else /* shift == 0 */
     692             :                 {
     693     6882240 :                     arith_encode_prob_escape( ecsq_inst, tab_vals, ECSQ_TAB_VALS_SIZE, sym );
     694             :                 }
     695             : 
     696     7394816 :                 if ( val != 0 )
     697             :                 {
     698     5440532 :                     arith_encode_bit( ecsq_inst, get_sign( val ) );
     699             :                 }
     700             :             }
     701             :         }
     702             :         else
     703             :         {
     704      210543 :             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      210543 :             arith_encode_bits( ecsq_inst, nonzero, 2 ); /* log_base2(ECSQ_NONZERO_MAX + 1) == 2 */
     712             : 
     713      210543 :             left1 = nonzero;
     714      210543 :             left0 = seg_length - nonzero;
     715             : 
     716     1894887 :             for ( i = seg_start; i <= seg_stop; ++i )
     717             :             {
     718     1684344 :                 val = input[i];
     719     1684344 :                 sym = (int16_t) abs( val );
     720             : 
     721             : #ifdef DEBUGGING
     722             :                 assert( sym <= 1 );
     723             : #endif
     724             : 
     725     1684344 :                 if ( left1 == 0 )
     726             :                 {
     727             : #ifdef DEBUGGING
     728             :                     assert( sym == 0 );
     729             : #endif
     730             :                 }
     731      685523 :                 else if ( left0 == 0 )
     732             :                 {
     733             : #ifdef DEBUGGING
     734             :                     assert( sym == 1 );
     735             : #endif
     736             :                 }
     737             :                 else
     738             :                 {
     739      643096 :                     count0 = left0 * ECSQ_tab_inverse[left0 + left1]; /* left0 * round(ECSQ_PROB_TOTAL / (left0 + left1)) */
     740      643096 :                     arith_encode_bit_prob( ecsq_inst, count0, sym );
     741             :                 }
     742             : 
     743     1684344 :                 if ( sym != 0 )
     744             :                 {
     745      247937 :                     arith_encode_bit( ecsq_inst, get_sign( val ) );
     746      247937 :                     --left1;
     747             :                 }
     748             :                 else
     749             :                 {
     750     1436407 :                     --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      226979 :     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      245432 : 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      245432 :     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      245432 :     max_bits_fixpt = max_bits * 1024; /* max_bits_fixpt is in 22Q10 fixed-point representation */
     811             : 
     812      245432 :     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      245432 :     sum_squared = 0.0f;
     825    10062712 :     for ( i = 0; i < N; ++i )
     826             :     {
     827     9817280 :         sum_squared += input[i] * input[i];
     828             :     }
     829             : 
     830      245432 :     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       17259 :         *global_gain_index_output = ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO;
     834       17259 :         if ( output != NULL )
     835             :         {
     836           0 :             set_f( output, 0.0f, N );
     837             :         }
     838             : 
     839       17259 :         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      228173 :     saved_encoding_active = ecsq_inst->encoding_active;
     844      228173 :     saved_bit_count_estimate = ecsq_inst->bit_count_estimate;
     845      228173 :     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      228173 :     target_ratio = powf( 10.0f, target_SNR / 10.0f );
     849      228173 :     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      228173 :     global_gain = sqrtf( target_sum_squared_error / ( 0.0833f * (float) N ) );
     854             :     /* quantize the estimated global_gain */
     855      228173 :     global_gain_index = ECSQ_quantize_gain( global_gain );
     856             : 
     857      228173 :     iteration = 0;
     858             : 
     859             :     /* do the quantization with the dequantized estimated global_gain_index found */
     860      228173 :     global_gain = ECSQ_dequantize_gain( global_gain_index );
     861      228173 :     global_gain_index_last = global_gain_index;
     862      228173 :     ECSQ_quantize_vector( input, global_gain, N, quantized_input );
     863             : 
     864      228173 :     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      228173 :     ++iteration;
     871      338225 :     while ( ( test_size > max_bits_fixpt ) && ( iteration < ECSQ_MAX_BITS_ITERATIONS ) )
     872             :     {
     873      110052 :         adjust_size = test_size - max_bits_fixpt;
     874             :         /* assume doubling the quantization step size will reduce the entropy with (up to) one bit */
     875      110052 :         adjust_global_gain_index = (int16_t) ceil( adjust_size / ( 1024.0f * N * log_base2( global_gain_step ) ) );
     876      110052 :         global_gain_index = min( (int16_t) ( global_gain_index + adjust_global_gain_index ), 126 );
     877             : 
     878      110052 :         global_gain = ECSQ_dequantize_gain( global_gain_index );
     879      110052 :         global_gain_index_last = global_gain_index;
     880      110052 :         ECSQ_quantize_vector( input, global_gain, N, quantized_input );
     881             : 
     882      110052 :         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      110052 :         ++iteration;
     889             :     }
     890             : 
     891      228173 :     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        2127 :         global_gain_index = (int16_t) min( global_gain_index + 1, 126 );
     899             :     }
     900             : 
     901             :     /* restore internal state */
     902      228173 :     ecsq_inst->encoding_active = saved_encoding_active;
     903      228173 :     ecsq_inst->bit_count_estimate = saved_bit_count_estimate;
     904             : 
     905             :     /* do the quantization with the dequantized final global_gain_index found */
     906      228173 :     global_gain = ECSQ_dequantize_gain( global_gain_index );
     907             : 
     908      228173 :     if ( global_gain_index != global_gain_index_last )
     909             :     {
     910        2127 :         ECSQ_quantize_vector( input, global_gain, N, quantized_input );
     911             :     }
     912             : 
     913      228173 :     global_gain = ECSQ_compute_optimal_gain( input, N, quantized_input );
     914             : 
     915      228173 :     if ( global_gain == 0.0f ) /* all values in quantized_input are zero */
     916             :     {
     917        1194 :         *global_gain_index_output = ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO;
     918        1194 :         if ( output != NULL )
     919             :         {
     920           0 :             set_f( output, 0.0f, N );
     921             :         }
     922             : 
     923        1194 :         return 0; /* nothing is coded when global gain index is ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO */
     924             :     }
     925             : 
     926      226979 :     global_gain_index = ECSQ_quantize_gain( global_gain );
     927      226979 :     *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      226979 :     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      226979 :     ECSQ_encode_raw( ecsq_inst, quantized_input, N );
     957             : 
     958      226979 :     return ecsq_inst->bit_count_estimate - saved_bit_count_estimate;
     959             : }

Generated by: LCOV version 1.14