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 : /* Limit, stabilize, convert and quantize NLSFs */
35 0 : void silk_process_NLSFs(
36 : silk_encoder_state *psEncC, /* I/O Encoder state */
37 : opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */
38 : opus_int16 pNLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */
39 : const opus_int16 prev_NLSFq_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */
40 : )
41 : {
42 : opus_int i, doInterpolate;
43 : opus_int NLSF_mu_Q20;
44 : opus_int16 i_sqr_Q15;
45 : opus_int16 pNLSF0_temp_Q15[ MAX_LPC_ORDER ];
46 : opus_int16 pNLSFW_QW[ MAX_LPC_ORDER ];
47 : opus_int16 pNLSFW0_temp_QW[ MAX_LPC_ORDER ];
48 :
49 0 : silk_assert( psEncC->speech_activity_Q8 >= 0 );
50 0 : silk_assert( psEncC->speech_activity_Q8 <= SILK_FIX_CONST( 1.0, 8 ) );
51 0 : silk_assert( psEncC->useInterpolatedNLSFs == 1 || psEncC->indices.NLSFInterpCoef_Q2 == ( 1 << 2 ) );
52 :
53 : /***********************/
54 : /* Calculate mu values */
55 : /***********************/
56 : /* NLSF_mu = 0.003 - 0.0015 * psEnc->speech_activity; */
57 0 : NLSF_mu_Q20 = silk_SMLAWB( SILK_FIX_CONST( 0.003, 20 ), SILK_FIX_CONST( -0.001, 28 ), psEncC->speech_activity_Q8 );
58 0 : if( psEncC->nb_subfr == 2 ) {
59 : /* Multiply by 1.5 for 10 ms packets */
60 0 : NLSF_mu_Q20 = silk_ADD_RSHIFT( NLSF_mu_Q20, NLSF_mu_Q20, 1 );
61 : }
62 :
63 0 : silk_assert( NLSF_mu_Q20 > 0 );
64 0 : silk_assert( NLSF_mu_Q20 <= SILK_FIX_CONST( 0.005, 20 ) );
65 :
66 : /* Calculate NLSF weights */
67 0 : silk_NLSF_VQ_weights_laroia( pNLSFW_QW, pNLSF_Q15, psEncC->predictLPCOrder );
68 :
69 : /* Update NLSF weights for interpolated NLSFs */
70 0 : doInterpolate = ( psEncC->useInterpolatedNLSFs == 1 ) && ( psEncC->indices.NLSFInterpCoef_Q2 < 4 );
71 0 : if( doInterpolate ) {
72 : /* Calculate the interpolated NLSF vector for the first half */
73 0 : silk_interpolate( pNLSF0_temp_Q15, prev_NLSFq_Q15, pNLSF_Q15,
74 0 : psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder );
75 :
76 : /* Calculate first half NLSF weights for the interpolated NLSFs */
77 0 : silk_NLSF_VQ_weights_laroia( pNLSFW0_temp_QW, pNLSF0_temp_Q15, psEncC->predictLPCOrder );
78 :
79 : /* Update NLSF weights with contribution from first half */
80 0 : i_sqr_Q15 = silk_LSHIFT( silk_SMULBB( psEncC->indices.NLSFInterpCoef_Q2, psEncC->indices.NLSFInterpCoef_Q2 ), 11 );
81 0 : for( i = 0; i < psEncC->predictLPCOrder; i++ ) {
82 0 : pNLSFW_QW[ i ] = silk_ADD16( silk_RSHIFT( pNLSFW_QW[ i ], 1 ), silk_RSHIFT(
83 : silk_SMULBB( pNLSFW0_temp_QW[ i ], i_sqr_Q15 ), 16) );
84 0 : silk_assert( pNLSFW_QW[ i ] >= 1 );
85 : }
86 : }
87 :
88 0 : silk_NLSF_encode( psEncC->indices.NLSFIndices, pNLSF_Q15, psEncC->psNLSF_CB, pNLSFW_QW,
89 0 : NLSF_mu_Q20, psEncC->NLSF_MSVQ_Survivors, psEncC->indices.signalType );
90 :
91 : /* Convert quantized NLSFs back to LPC coefficients */
92 0 : silk_NLSF2A( PredCoef_Q12[ 1 ], pNLSF_Q15, psEncC->predictLPCOrder, psEncC->arch );
93 :
94 0 : if( doInterpolate ) {
95 : /* Calculate the interpolated, quantized LSF vector for the first half */
96 0 : silk_interpolate( pNLSF0_temp_Q15, prev_NLSFq_Q15, pNLSF_Q15,
97 0 : psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder );
98 :
99 : /* Convert back to LPC coefficients */
100 0 : silk_NLSF2A( PredCoef_Q12[ 0 ], pNLSF0_temp_Q15, psEncC->predictLPCOrder, psEncC->arch );
101 :
102 : } else {
103 : /* Copy LPC coefficients for first half from second half */
104 0 : silk_assert( psEncC->predictLPCOrder <= MAX_LPC_ORDER );
105 0 : silk_memcpy( PredCoef_Q12[ 0 ], PredCoef_Q12[ 1 ], psEncC->predictLPCOrder * sizeof( opus_int16 ) );
106 : }
107 0 : }
|