Coverage Report

Created: 2025-11-09 07:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opus/silk/NLSF_del_dec_quant.c
Line
Count
Source
1
/***********************************************************************
2
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3
Redistribution and use in source and binary forms, with or without
4
modification, are permitted provided that the following conditions
5
are met:
6
- Redistributions of source code must retain the above copyright notice,
7
this list of conditions and the following disclaimer.
8
- Redistributions in binary form must reproduce the above copyright
9
notice, this list of conditions and the following disclaimer in the
10
documentation and/or other materials provided with the distribution.
11
- Neither the name of Internet Society, IETF or IETF Trust, nor the
12
names of specific contributors, may be used to endorse or promote
13
products derived from this software without specific prior written
14
permission.
15
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25
POSSIBILITY OF SUCH DAMAGE.
26
***********************************************************************/
27
28
#ifdef HAVE_CONFIG_H
29
#include "config.h"
30
#endif
31
32
#include "main.h"
33
34
/* Delayed-decision quantizer for NLSF residuals */
35
opus_int32 silk_NLSF_del_dec_quant(                             /* O    Returns RD value in Q25                     */
36
    opus_int8                   indices[],                      /* O    Quantization indices [ order ]              */
37
    const opus_int16            x_Q10[],                        /* I    Input [ order ]                             */
38
    const opus_int16            w_Q5[],                         /* I    Weights [ order ]                           */
39
    const opus_uint8            pred_coef_Q8[],                 /* I    Backward predictor coefs [ order ]          */
40
    const opus_int16            ec_ix[],                        /* I    Indices to entropy coding tables [ order ]  */
41
    const opus_uint8            ec_rates_Q5[],                  /* I    Rates []                                    */
42
    const opus_int              quant_step_size_Q16,            /* I    Quantization step size                      */
43
    const opus_int16            inv_quant_step_size_Q6,         /* I    Inverse quantization step size              */
44
    const opus_int32            mu_Q20,                         /* I    R/D tradeoff                                */
45
    const opus_int16            order                           /* I    Number of input values                      */
46
)
47
4.27M
{
48
4.27M
    opus_int         i, j, nStates, ind_tmp, ind_min_max, ind_max_min, in_Q10, res_Q10;
49
4.27M
    opus_int         pred_Q10, diff_Q10, rate0_Q5, rate1_Q5;
50
4.27M
    opus_int16       out0_Q10, out1_Q10;
51
4.27M
    opus_int32       RD_tmp_Q25, min_Q25, min_max_Q25, max_min_Q25;
52
4.27M
    opus_int         ind_sort[         NLSF_QUANT_DEL_DEC_STATES ];
53
4.27M
    opus_int8        ind[              NLSF_QUANT_DEL_DEC_STATES ][ MAX_LPC_ORDER ];
54
4.27M
    opus_int16       prev_out_Q10[ 2 * NLSF_QUANT_DEL_DEC_STATES ];
55
4.27M
    opus_int32       RD_Q25[       2 * NLSF_QUANT_DEL_DEC_STATES ];
56
4.27M
    opus_int32       RD_min_Q25[       NLSF_QUANT_DEL_DEC_STATES ];
57
4.27M
    opus_int32       RD_max_Q25[       NLSF_QUANT_DEL_DEC_STATES ];
58
4.27M
    const opus_uint8 *rates_Q5;
59
60
4.27M
    opus_int out0_Q10_table[2 * NLSF_QUANT_MAX_AMPLITUDE_EXT];
61
4.27M
    opus_int out1_Q10_table[2 * NLSF_QUANT_MAX_AMPLITUDE_EXT];
62
63
89.8M
    for (i = -NLSF_QUANT_MAX_AMPLITUDE_EXT; i <= NLSF_QUANT_MAX_AMPLITUDE_EXT-1; i++)
64
85.5M
    {
65
85.5M
        out0_Q10 = silk_LSHIFT( i, 10 );
66
85.5M
        out1_Q10 = silk_ADD16( out0_Q10, 1024 );
67
85.5M
        if( i > 0 ) {
68
38.5M
            out0_Q10 = silk_SUB16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
69
38.5M
            out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
70
47.0M
        } else if( i == 0 ) {
71
4.27M
            out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
72
42.7M
        } else if( i == -1 ) {
73
4.27M
            out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
74
38.5M
        } else {
75
38.5M
            out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
76
38.5M
            out1_Q10 = silk_ADD16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
77
38.5M
        }
78
85.5M
        out0_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_RSHIFT( silk_SMULBB( out0_Q10, quant_step_size_Q16 ), 16 );
79
85.5M
        out1_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_RSHIFT( silk_SMULBB( out1_Q10, quant_step_size_Q16 ), 16 );
80
85.5M
    }
81
82
4.27M
    silk_assert( (NLSF_QUANT_DEL_DEC_STATES & (NLSF_QUANT_DEL_DEC_STATES-1)) == 0 );     /* must be power of two */
83
84
4.27M
    nStates = 1;
85
4.27M
    RD_Q25[ 0 ] = 0;
86
4.27M
    prev_out_Q10[ 0 ] = 0;
87
53.3M
    for( i = order - 1; i >= 0; i-- ) {
88
49.0M
        rates_Q5 = &ec_rates_Q5[ ec_ix[ i ] ];
89
49.0M
        in_Q10 = x_Q10[ i ];
90
223M
        for( j = 0; j < nStates; j++ ) {
91
174M
            pred_Q10 = silk_RSHIFT( silk_SMULBB( (opus_int16)pred_coef_Q8[ i ], prev_out_Q10[ j ] ), 8 );
92
174M
            res_Q10  = silk_SUB16( in_Q10, pred_Q10 );
93
174M
            ind_tmp  = silk_RSHIFT( silk_SMULBB( inv_quant_step_size_Q6, res_Q10 ), 16 );
94
174M
            ind_tmp  = silk_LIMIT( ind_tmp, -NLSF_QUANT_MAX_AMPLITUDE_EXT, NLSF_QUANT_MAX_AMPLITUDE_EXT-1 );
95
174M
            ind[ j ][ i ] = (opus_int8)ind_tmp;
96
97
            /* compute outputs for ind_tmp and ind_tmp + 1 */
98
174M
            out0_Q10 = out0_Q10_table[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE_EXT ];
99
174M
            out1_Q10 = out1_Q10_table[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE_EXT ];
100
101
174M
            out0_Q10  = silk_ADD16( out0_Q10, pred_Q10 );
102
174M
            out1_Q10  = silk_ADD16( out1_Q10, pred_Q10 );
103
174M
            prev_out_Q10[ j           ] = out0_Q10;
104
174M
            prev_out_Q10[ j + nStates ] = out1_Q10;
105
106
            /* compute RD for ind_tmp and ind_tmp + 1 */
107
174M
            if( ind_tmp + 1 >= NLSF_QUANT_MAX_AMPLITUDE ) {
108
811k
                if( ind_tmp + 1 == NLSF_QUANT_MAX_AMPLITUDE ) {
109
642k
                    rate0_Q5 = rates_Q5[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE ];
110
642k
                    rate1_Q5 = 280;
111
642k
                } else {
112
168k
                    rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, 43, ind_tmp );
113
168k
                    rate1_Q5 = silk_ADD16( rate0_Q5, 43 );
114
168k
                }
115
174M
            } else if( ind_tmp <= -NLSF_QUANT_MAX_AMPLITUDE ) {
116
1.39M
                if( ind_tmp == -NLSF_QUANT_MAX_AMPLITUDE ) {
117
958k
                    rate0_Q5 = 280;
118
958k
                    rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ];
119
958k
                } else {
120
431k
                    rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, -43, ind_tmp );
121
431k
                    rate1_Q5 = silk_SUB16( rate0_Q5, 43 );
122
431k
                }
123
172M
            } else {
124
172M
                rate0_Q5 = rates_Q5[ ind_tmp +     NLSF_QUANT_MAX_AMPLITUDE ];
125
172M
                rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ];
126
172M
            }
127
174M
            RD_tmp_Q25            = RD_Q25[ j ];
128
174M
            diff_Q10              = silk_SUB16( in_Q10, out0_Q10 );
129
174M
            RD_Q25[ j ]           = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate0_Q5 );
130
174M
            diff_Q10              = silk_SUB16( in_Q10, out1_Q10 );
131
174M
            RD_Q25[ j + nStates ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate1_Q5 );
132
174M
        }
133
134
49.0M
        if( nStates <= NLSF_QUANT_DEL_DEC_STATES/2 ) {
135
            /* double number of states and copy */
136
21.3M
            for( j = 0; j < nStates; j++ ) {
137
12.8M
                ind[ j + nStates ][ i ] = ind[ j ][ i ] + 1;
138
12.8M
            }
139
8.55M
            nStates = silk_LSHIFT( nStates, 1 );
140
17.1M
            for( j = nStates; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
141
8.55M
                ind[ j ][ i ] = ind[ j - nStates ][ i ];
142
8.55M
            }
143
40.5M
        } else {
144
            /* sort lower and upper half of RD_Q25, pairwise */
145
202M
            for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
146
162M
                if( RD_Q25[ j ] > RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] ) {
147
80.9M
                    RD_max_Q25[ j ]                         = RD_Q25[ j ];
148
80.9M
                    RD_min_Q25[ j ]                         = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ];
149
80.9M
                    RD_Q25[ j ]                             = RD_min_Q25[ j ];
150
80.9M
                    RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] = RD_max_Q25[ j ];
151
                    /* swap prev_out values */
152
80.9M
                    out0_Q10 = prev_out_Q10[ j ];
153
80.9M
                    prev_out_Q10[ j ] = prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ];
154
80.9M
                    prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ] = out0_Q10;
155
80.9M
                    ind_sort[ j ] = j + NLSF_QUANT_DEL_DEC_STATES;
156
81.0M
                } else {
157
81.0M
                    RD_min_Q25[ j ] = RD_Q25[ j ];
158
81.0M
                    RD_max_Q25[ j ] = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ];
159
81.0M
                    ind_sort[ j ] = j;
160
81.0M
                }
161
162M
            }
162
            /* compare the highest RD values of the winning half with the lowest one in the losing half, and copy if necessary */
163
            /* afterwards ind_sort[] will contain the indices of the NLSF_QUANT_DEL_DEC_STATES winning RD values */
164
68.2M
            while( 1 ) {
165
68.2M
                min_max_Q25 = silk_int32_MAX;
166
68.2M
                max_min_Q25 = 0;
167
68.2M
                ind_min_max = 0;
168
68.2M
                ind_max_min = 0;
169
341M
                for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
170
273M
                    if( min_max_Q25 > RD_max_Q25[ j ] ) {
171
132M
                        min_max_Q25 = RD_max_Q25[ j ];
172
132M
                        ind_min_max = j;
173
132M
                    }
174
273M
                    if( max_min_Q25 < RD_min_Q25[ j ] ) {
175
135M
                        max_min_Q25 = RD_min_Q25[ j ];
176
135M
                        ind_max_min = j;
177
135M
                    }
178
273M
                }
179
68.2M
                if( min_max_Q25 >= max_min_Q25 ) {
180
40.5M
                    break;
181
40.5M
                }
182
                /* copy ind_min_max to ind_max_min */
183
27.7M
                ind_sort[     ind_max_min ] = ind_sort[     ind_min_max ] ^ NLSF_QUANT_DEL_DEC_STATES;
184
27.7M
                RD_Q25[       ind_max_min ] = RD_Q25[       ind_min_max + NLSF_QUANT_DEL_DEC_STATES ];
185
27.7M
                prev_out_Q10[ ind_max_min ] = prev_out_Q10[ ind_min_max + NLSF_QUANT_DEL_DEC_STATES ];
186
27.7M
                RD_min_Q25[   ind_max_min ] = 0;
187
27.7M
                RD_max_Q25[   ind_min_max ] = silk_int32_MAX;
188
27.7M
                silk_memcpy( ind[ ind_max_min ], ind[ ind_min_max ], MAX_LPC_ORDER * sizeof( opus_int8 ) );
189
27.7M
            }
190
            /* increment index if it comes from the upper half */
191
202M
            for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
192
162M
                ind[ j ][ i ] += silk_RSHIFT( ind_sort[ j ], NLSF_QUANT_DEL_DEC_STATES_LOG2 );
193
162M
            }
194
40.5M
        }
195
49.0M
    }
196
197
    /* last sample: find winner, copy indices and return RD value */
198
4.27M
    ind_tmp = 0;
199
4.27M
    min_Q25 = silk_int32_MAX;
200
38.5M
    for( j = 0; j < 2 * NLSF_QUANT_DEL_DEC_STATES; j++ ) {
201
34.2M
        if( min_Q25 > RD_Q25[ j ] ) {
202
8.81M
            min_Q25 = RD_Q25[ j ];
203
8.81M
            ind_tmp = j;
204
8.81M
        }
205
34.2M
    }
206
53.3M
    for( j = 0; j < order; j++ ) {
207
49.0M
        indices[ j ] = ind[ ind_tmp & ( NLSF_QUANT_DEL_DEC_STATES - 1 ) ][ j ];
208
49.0M
        silk_assert( indices[ j ] >= -NLSF_QUANT_MAX_AMPLITUDE_EXT );
209
49.0M
        silk_assert( indices[ j ] <=  NLSF_QUANT_MAX_AMPLITUDE_EXT );
210
49.0M
    }
211
4.27M
    indices[ 0 ] += silk_RSHIFT( ind_tmp, NLSF_QUANT_DEL_DEC_STATES_LOG2 );
212
4.27M
    silk_assert( indices[ 0 ] <= NLSF_QUANT_MAX_AMPLITUDE_EXT );
213
4.27M
    silk_assert( min_Q25 >= 0 );
214
4.27M
    return min_Q25;
215
4.27M
}