Line data Source code
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 0 : 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 : {
48 : opus_int i, j, nStates, ind_tmp, ind_min_max, ind_max_min, in_Q10, res_Q10;
49 : opus_int pred_Q10, diff_Q10, rate0_Q5, rate1_Q5;
50 : opus_int16 out0_Q10, out1_Q10;
51 : opus_int32 RD_tmp_Q25, min_Q25, min_max_Q25, max_min_Q25;
52 : opus_int ind_sort[ NLSF_QUANT_DEL_DEC_STATES ];
53 : opus_int8 ind[ NLSF_QUANT_DEL_DEC_STATES ][ MAX_LPC_ORDER ];
54 : opus_int16 prev_out_Q10[ 2 * NLSF_QUANT_DEL_DEC_STATES ];
55 : opus_int32 RD_Q25[ 2 * NLSF_QUANT_DEL_DEC_STATES ];
56 : opus_int32 RD_min_Q25[ NLSF_QUANT_DEL_DEC_STATES ];
57 : opus_int32 RD_max_Q25[ NLSF_QUANT_DEL_DEC_STATES ];
58 : const opus_uint8 *rates_Q5;
59 :
60 : opus_int out0_Q10_table[2 * NLSF_QUANT_MAX_AMPLITUDE_EXT];
61 : opus_int out1_Q10_table[2 * NLSF_QUANT_MAX_AMPLITUDE_EXT];
62 :
63 0 : for (i = -NLSF_QUANT_MAX_AMPLITUDE_EXT; i <= NLSF_QUANT_MAX_AMPLITUDE_EXT-1; i++)
64 : {
65 0 : out0_Q10 = silk_LSHIFT( i, 10 );
66 0 : out1_Q10 = silk_ADD16( out0_Q10, 1024 );
67 0 : if( i > 0 ) {
68 0 : out0_Q10 = silk_SUB16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
69 0 : out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
70 0 : } else if( i == 0 ) {
71 0 : out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
72 0 : } else if( i == -1 ) {
73 0 : out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
74 : } else {
75 0 : out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
76 0 : out1_Q10 = silk_ADD16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
77 : }
78 0 : out0_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_RSHIFT( silk_SMULBB( out0_Q10, quant_step_size_Q16 ), 16 );
79 0 : out1_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_RSHIFT( silk_SMULBB( out1_Q10, quant_step_size_Q16 ), 16 );
80 : }
81 :
82 : silk_assert( (NLSF_QUANT_DEL_DEC_STATES & (NLSF_QUANT_DEL_DEC_STATES-1)) == 0 ); /* must be power of two */
83 :
84 0 : nStates = 1;
85 0 : RD_Q25[ 0 ] = 0;
86 0 : prev_out_Q10[ 0 ] = 0;
87 0 : for( i = order - 1; i >= 0; i-- ) {
88 0 : rates_Q5 = &ec_rates_Q5[ ec_ix[ i ] ];
89 0 : in_Q10 = x_Q10[ i ];
90 0 : for( j = 0; j < nStates; j++ ) {
91 0 : pred_Q10 = silk_RSHIFT( silk_SMULBB( (opus_int16)pred_coef_Q8[ i ], prev_out_Q10[ j ] ), 8 );
92 0 : res_Q10 = silk_SUB16( in_Q10, pred_Q10 );
93 0 : ind_tmp = silk_RSHIFT( silk_SMULBB( inv_quant_step_size_Q6, res_Q10 ), 16 );
94 0 : ind_tmp = silk_LIMIT( ind_tmp, -NLSF_QUANT_MAX_AMPLITUDE_EXT, NLSF_QUANT_MAX_AMPLITUDE_EXT-1 );
95 0 : ind[ j ][ i ] = (opus_int8)ind_tmp;
96 :
97 : /* compute outputs for ind_tmp and ind_tmp + 1 */
98 0 : out0_Q10 = out0_Q10_table[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE_EXT ];
99 0 : out1_Q10 = out1_Q10_table[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE_EXT ];
100 :
101 0 : out0_Q10 = silk_ADD16( out0_Q10, pred_Q10 );
102 0 : out1_Q10 = silk_ADD16( out1_Q10, pred_Q10 );
103 0 : prev_out_Q10[ j ] = out0_Q10;
104 0 : prev_out_Q10[ j + nStates ] = out1_Q10;
105 :
106 : /* compute RD for ind_tmp and ind_tmp + 1 */
107 0 : if( ind_tmp + 1 >= NLSF_QUANT_MAX_AMPLITUDE ) {
108 0 : if( ind_tmp + 1 == NLSF_QUANT_MAX_AMPLITUDE ) {
109 0 : rate0_Q5 = rates_Q5[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE ];
110 0 : rate1_Q5 = 280;
111 : } else {
112 0 : rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, 43, ind_tmp );
113 0 : rate1_Q5 = silk_ADD16( rate0_Q5, 43 );
114 : }
115 0 : } else if( ind_tmp <= -NLSF_QUANT_MAX_AMPLITUDE ) {
116 0 : if( ind_tmp == -NLSF_QUANT_MAX_AMPLITUDE ) {
117 0 : rate0_Q5 = 280;
118 0 : rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ];
119 : } else {
120 0 : rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, -43, ind_tmp );
121 0 : rate1_Q5 = silk_SUB16( rate0_Q5, 43 );
122 : }
123 : } else {
124 0 : rate0_Q5 = rates_Q5[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE ];
125 0 : rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ];
126 : }
127 0 : RD_tmp_Q25 = RD_Q25[ j ];
128 0 : diff_Q10 = silk_SUB16( in_Q10, out0_Q10 );
129 0 : RD_Q25[ j ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate0_Q5 );
130 0 : diff_Q10 = silk_SUB16( in_Q10, out1_Q10 );
131 0 : 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 : }
133 :
134 0 : if( nStates <= NLSF_QUANT_DEL_DEC_STATES/2 ) {
135 : /* double number of states and copy */
136 0 : for( j = 0; j < nStates; j++ ) {
137 0 : ind[ j + nStates ][ i ] = ind[ j ][ i ] + 1;
138 : }
139 0 : nStates = silk_LSHIFT( nStates, 1 );
140 0 : for( j = nStates; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
141 0 : ind[ j ][ i ] = ind[ j - nStates ][ i ];
142 : }
143 : } else {
144 : /* sort lower and upper half of RD_Q25, pairwise */
145 0 : for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
146 0 : if( RD_Q25[ j ] > RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] ) {
147 0 : RD_max_Q25[ j ] = RD_Q25[ j ];
148 0 : RD_min_Q25[ j ] = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ];
149 0 : RD_Q25[ j ] = RD_min_Q25[ j ];
150 0 : RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] = RD_max_Q25[ j ];
151 : /* swap prev_out values */
152 0 : out0_Q10 = prev_out_Q10[ j ];
153 0 : prev_out_Q10[ j ] = prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ];
154 0 : prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ] = out0_Q10;
155 0 : ind_sort[ j ] = j + NLSF_QUANT_DEL_DEC_STATES;
156 : } else {
157 0 : RD_min_Q25[ j ] = RD_Q25[ j ];
158 0 : RD_max_Q25[ j ] = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ];
159 0 : ind_sort[ j ] = j;
160 : }
161 : }
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 : while( 1 ) {
165 0 : min_max_Q25 = silk_int32_MAX;
166 0 : max_min_Q25 = 0;
167 0 : ind_min_max = 0;
168 0 : ind_max_min = 0;
169 0 : for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
170 0 : if( min_max_Q25 > RD_max_Q25[ j ] ) {
171 0 : min_max_Q25 = RD_max_Q25[ j ];
172 0 : ind_min_max = j;
173 : }
174 0 : if( max_min_Q25 < RD_min_Q25[ j ] ) {
175 0 : max_min_Q25 = RD_min_Q25[ j ];
176 0 : ind_max_min = j;
177 : }
178 : }
179 0 : if( min_max_Q25 >= max_min_Q25 ) {
180 0 : break;
181 : }
182 : /* copy ind_min_max to ind_max_min */
183 0 : ind_sort[ ind_max_min ] = ind_sort[ ind_min_max ] ^ NLSF_QUANT_DEL_DEC_STATES;
184 0 : RD_Q25[ ind_max_min ] = RD_Q25[ ind_min_max + NLSF_QUANT_DEL_DEC_STATES ];
185 0 : prev_out_Q10[ ind_max_min ] = prev_out_Q10[ ind_min_max + NLSF_QUANT_DEL_DEC_STATES ];
186 0 : RD_min_Q25[ ind_max_min ] = 0;
187 0 : RD_max_Q25[ ind_min_max ] = silk_int32_MAX;
188 0 : silk_memcpy( ind[ ind_max_min ], ind[ ind_min_max ], MAX_LPC_ORDER * sizeof( opus_int8 ) );
189 : }
190 : /* increment index if it comes from the upper half */
191 0 : for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
192 0 : ind[ j ][ i ] += silk_RSHIFT( ind_sort[ j ], NLSF_QUANT_DEL_DEC_STATES_LOG2 );
193 : }
194 : }
195 : }
196 :
197 : /* last sample: find winner, copy indices and return RD value */
198 0 : ind_tmp = 0;
199 0 : min_Q25 = silk_int32_MAX;
200 0 : for( j = 0; j < 2 * NLSF_QUANT_DEL_DEC_STATES; j++ ) {
201 0 : if( min_Q25 > RD_Q25[ j ] ) {
202 0 : min_Q25 = RD_Q25[ j ];
203 0 : ind_tmp = j;
204 : }
205 : }
206 0 : for( j = 0; j < order; j++ ) {
207 0 : indices[ j ] = ind[ ind_tmp & ( NLSF_QUANT_DEL_DEC_STATES - 1 ) ][ j ];
208 0 : silk_assert( indices[ j ] >= -NLSF_QUANT_MAX_AMPLITUDE_EXT );
209 0 : silk_assert( indices[ j ] <= NLSF_QUANT_MAX_AMPLITUDE_EXT );
210 : }
211 0 : indices[ 0 ] += silk_RSHIFT( ind_tmp, NLSF_QUANT_DEL_DEC_STATES_LOG2 );
212 0 : silk_assert( indices[ 0 ] <= NLSF_QUANT_MAX_AMPLITUDE_EXT );
213 0 : silk_assert( min_Q25 >= 0 );
214 0 : return min_Q25;
215 : }
|