LCOV - code coverage report
Current view: top level - lib_enc - ivas_stereo_eclvq_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 235 243 96.7 %
Date: 2025-05-23 08:37:30 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      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             : }

Generated by: LCOV version 1.14