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 : #include "stack_alloc.h"
34 :
35 : /***********************/
36 : /* NLSF vector encoder */
37 : /***********************/
38 0 : opus_int32 silk_NLSF_encode( /* O Returns RD value in Q25 */
39 : opus_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */
40 : opus_int16 *pNLSF_Q15, /* I/O (Un)quantized NLSF vector [ LPC_ORDER ] */
41 : const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */
42 : const opus_int16 *pW_Q2, /* I NLSF weight vector [ LPC_ORDER ] */
43 : const opus_int NLSF_mu_Q20, /* I Rate weight for the RD optimization */
44 : const opus_int nSurvivors, /* I Max survivors after first stage */
45 : const opus_int signalType /* I Signal type: 0/1/2 */
46 : )
47 : {
48 : opus_int i, s, ind1, bestIndex, prob_Q8, bits_q7;
49 : opus_int32 W_tmp_Q9, ret;
50 : VARDECL( opus_int32, err_Q24 );
51 : VARDECL( opus_int32, RD_Q25 );
52 : VARDECL( opus_int, tempIndices1 );
53 : VARDECL( opus_int8, tempIndices2 );
54 : opus_int16 res_Q10[ MAX_LPC_ORDER ];
55 : opus_int16 NLSF_tmp_Q15[ MAX_LPC_ORDER ];
56 : opus_int16 W_adj_Q5[ MAX_LPC_ORDER ];
57 : opus_uint8 pred_Q8[ MAX_LPC_ORDER ];
58 : opus_int16 ec_ix[ MAX_LPC_ORDER ];
59 : const opus_uint8 *pCB_element, *iCDF_ptr;
60 : const opus_int16 *pCB_Wght_Q9;
61 : SAVE_STACK;
62 :
63 0 : silk_assert( signalType >= 0 && signalType <= 2 );
64 0 : silk_assert( NLSF_mu_Q20 <= 32767 && NLSF_mu_Q20 >= 0 );
65 :
66 : /* NLSF stabilization */
67 0 : silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order );
68 :
69 : /* First stage: VQ */
70 0 : ALLOC( err_Q24, psNLSF_CB->nVectors, opus_int32 );
71 0 : silk_NLSF_VQ( err_Q24, pNLSF_Q15, psNLSF_CB->CB1_NLSF_Q8, psNLSF_CB->CB1_Wght_Q9, psNLSF_CB->nVectors, psNLSF_CB->order );
72 :
73 : /* Sort the quantization errors */
74 0 : ALLOC( tempIndices1, nSurvivors, opus_int );
75 0 : silk_insertion_sort_increasing( err_Q24, tempIndices1, psNLSF_CB->nVectors, nSurvivors );
76 :
77 0 : ALLOC( RD_Q25, nSurvivors, opus_int32 );
78 0 : ALLOC( tempIndices2, nSurvivors * MAX_LPC_ORDER, opus_int8 );
79 :
80 : /* Loop over survivors */
81 0 : for( s = 0; s < nSurvivors; s++ ) {
82 0 : ind1 = tempIndices1[ s ];
83 :
84 : /* Residual after first stage */
85 0 : pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ ind1 * psNLSF_CB->order ];
86 0 : pCB_Wght_Q9 = &psNLSF_CB->CB1_Wght_Q9[ ind1 * psNLSF_CB->order ];
87 0 : for( i = 0; i < psNLSF_CB->order; i++ ) {
88 0 : NLSF_tmp_Q15[ i ] = silk_LSHIFT16( (opus_int16)pCB_element[ i ], 7 );
89 0 : W_tmp_Q9 = pCB_Wght_Q9[ i ];
90 0 : res_Q10[ i ] = (opus_int16)silk_RSHIFT( silk_SMULBB( pNLSF_Q15[ i ] - NLSF_tmp_Q15[ i ], W_tmp_Q9 ), 14 );
91 0 : W_adj_Q5[ i ] = silk_DIV32_varQ( (opus_int32)pW_Q2[ i ], silk_SMULBB( W_tmp_Q9, W_tmp_Q9 ), 21 );
92 : }
93 :
94 : /* Unpack entropy table indices and predictor for current CB1 index */
95 0 : silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, ind1 );
96 :
97 : /* Trellis quantizer */
98 0 : RD_Q25[ s ] = silk_NLSF_del_dec_quant( &tempIndices2[ s * MAX_LPC_ORDER ], res_Q10, W_adj_Q5, pred_Q8, ec_ix,
99 0 : psNLSF_CB->ec_Rates_Q5, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->invQuantStepSize_Q6, NLSF_mu_Q20, psNLSF_CB->order );
100 :
101 : /* Add rate for first stage */
102 0 : iCDF_ptr = &psNLSF_CB->CB1_iCDF[ ( signalType >> 1 ) * psNLSF_CB->nVectors ];
103 0 : if( ind1 == 0 ) {
104 0 : prob_Q8 = 256 - iCDF_ptr[ ind1 ];
105 : } else {
106 0 : prob_Q8 = iCDF_ptr[ ind1 - 1 ] - iCDF_ptr[ ind1 ];
107 : }
108 0 : bits_q7 = ( 8 << 7 ) - silk_lin2log( prob_Q8 );
109 0 : RD_Q25[ s ] = silk_SMLABB( RD_Q25[ s ], bits_q7, silk_RSHIFT( NLSF_mu_Q20, 2 ) );
110 : }
111 :
112 : /* Find the lowest rate-distortion error */
113 0 : silk_insertion_sort_increasing( RD_Q25, &bestIndex, nSurvivors, 1 );
114 :
115 0 : NLSFIndices[ 0 ] = (opus_int8)tempIndices1[ bestIndex ];
116 0 : silk_memcpy( &NLSFIndices[ 1 ], &tempIndices2[ bestIndex * MAX_LPC_ORDER ], psNLSF_CB->order * sizeof( opus_int8 ) );
117 :
118 : /* Decode */
119 0 : silk_NLSF_decode( pNLSF_Q15, NLSFIndices, psNLSF_CB );
120 :
121 0 : ret = RD_Q25[ 0 ];
122 : RESTORE_STACK;
123 0 : return ret;
124 : }
|