/src/opus/silk/fixed/find_pitch_lags_FIX.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_FIX.h" |
33 | | #include "stack_alloc.h" |
34 | | #include "tuning_parameters.h" |
35 | | |
36 | | /* Find pitch lags */ |
37 | | void silk_find_pitch_lags_FIX( |
38 | | silk_encoder_state_FIX *psEnc, /* I/O encoder state */ |
39 | | silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ |
40 | | opus_int16 res[], /* O residual */ |
41 | | const opus_int16 x[], /* I Speech signal */ |
42 | | int arch /* I Run-time architecture */ |
43 | | ) |
44 | 26.0M | { |
45 | 26.0M | opus_int buf_len, i, scale; |
46 | 26.0M | opus_int32 thrhld_Q13, res_nrg; |
47 | 26.0M | const opus_int16 *x_ptr; |
48 | 26.0M | VARDECL( opus_int16, Wsig ); |
49 | 26.0M | opus_int16 *Wsig_ptr; |
50 | 26.0M | opus_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ]; |
51 | 26.0M | opus_int16 rc_Q15[ MAX_FIND_PITCH_LPC_ORDER ]; |
52 | 26.0M | opus_int32 A_Q24[ MAX_FIND_PITCH_LPC_ORDER ]; |
53 | 26.0M | opus_int16 A_Q12[ MAX_FIND_PITCH_LPC_ORDER ]; |
54 | 26.0M | SAVE_STACK; |
55 | | |
56 | | /******************************************/ |
57 | | /* Set up buffer lengths etc based on Fs */ |
58 | | /******************************************/ |
59 | 26.0M | buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length; |
60 | | |
61 | | /* Safety check */ |
62 | 26.0M | celt_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length ); |
63 | | |
64 | | /*************************************/ |
65 | | /* Estimate LPC AR coefficients */ |
66 | | /*************************************/ |
67 | | |
68 | | /* Calculate windowed signal */ |
69 | | |
70 | 26.0M | ALLOC( Wsig, psEnc->sCmn.pitch_LPC_win_length, opus_int16 ); |
71 | | |
72 | | /* First LA_LTP samples */ |
73 | 26.0M | x_ptr = x + buf_len - psEnc->sCmn.pitch_LPC_win_length; |
74 | 26.0M | Wsig_ptr = Wsig; |
75 | 26.0M | silk_apply_sine_window( Wsig_ptr, x_ptr, 1, psEnc->sCmn.la_pitch ); |
76 | | |
77 | | /* Middle un - windowed samples */ |
78 | 26.0M | Wsig_ptr += psEnc->sCmn.la_pitch; |
79 | 26.0M | x_ptr += psEnc->sCmn.la_pitch; |
80 | 26.0M | silk_memcpy( Wsig_ptr, x_ptr, ( psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( opus_int16 ) ); |
81 | | |
82 | | /* Last LA_LTP samples */ |
83 | 26.0M | Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ); |
84 | 26.0M | x_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ); |
85 | 26.0M | silk_apply_sine_window( Wsig_ptr, x_ptr, 2, psEnc->sCmn.la_pitch ); |
86 | | |
87 | | /* Calculate autocorrelation sequence */ |
88 | 26.0M | silk_autocorr( auto_corr, &scale, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1, arch ); |
89 | | |
90 | | /* Add white noise, as fraction of energy */ |
91 | 26.0M | auto_corr[ 0 ] = silk_SMLAWB( auto_corr[ 0 ], auto_corr[ 0 ], SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ) + 1; |
92 | | |
93 | | /* Calculate the reflection coefficients using schur */ |
94 | 26.0M | res_nrg = silk_schur( rc_Q15, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder ); |
95 | | |
96 | | /* Prediction gain */ |
97 | 26.0M | psEncCtrl->predGain_Q16 = silk_DIV32_varQ( auto_corr[ 0 ], silk_max_int( res_nrg, 1 ), 16 ); |
98 | | |
99 | | /* Convert reflection coefficients to prediction coefficients */ |
100 | 26.0M | silk_k2a( A_Q24, rc_Q15, psEnc->sCmn.pitchEstimationLPCOrder ); |
101 | | |
102 | | /* Convert From 32 bit Q24 to 16 bit Q12 coefs */ |
103 | 233M | for( i = 0; i < psEnc->sCmn.pitchEstimationLPCOrder; i++ ) { |
104 | 207M | A_Q12[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT( A_Q24[ i ], 12 ) ); |
105 | 207M | } |
106 | | |
107 | | /* Do BWE */ |
108 | 26.0M | silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SILK_FIX_CONST( FIND_PITCH_BANDWIDTH_EXPANSION, 16 ) ); |
109 | | |
110 | | /*****************************************/ |
111 | | /* LPC analysis filtering */ |
112 | | /*****************************************/ |
113 | 26.0M | silk_LPC_analysis_filter( res, x, A_Q12, buf_len, psEnc->sCmn.pitchEstimationLPCOrder, psEnc->sCmn.arch ); |
114 | | |
115 | 26.0M | if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) { |
116 | | /* Threshold for pitch estimator */ |
117 | 517k | thrhld_Q13 = SILK_FIX_CONST( 0.6, 13 ); |
118 | 517k | thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.004, 13 ), psEnc->sCmn.pitchEstimationLPCOrder ); |
119 | 517k | thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1, 21 ), psEnc->sCmn.speech_activity_Q8 ); |
120 | 517k | thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.15, 13 ), silk_RSHIFT( psEnc->sCmn.prevSignalType, 1 ) ); |
121 | 517k | thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1, 14 ), psEnc->sCmn.input_tilt_Q15 ); |
122 | 517k | thrhld_Q13 = silk_SAT16( thrhld_Q13 ); |
123 | | |
124 | | /*****************************************/ |
125 | | /* Call pitch estimator */ |
126 | | /*****************************************/ |
127 | 517k | if( silk_pitch_analysis_core( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, &psEnc->sCmn.indices.contourIndex, |
128 | 517k | &psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16, |
129 | 517k | (opus_int)thrhld_Q13, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr, |
130 | 517k | psEnc->sCmn.arch) == 0 ) |
131 | 251k | { |
132 | 251k | psEnc->sCmn.indices.signalType = TYPE_VOICED; |
133 | 265k | } else { |
134 | 265k | psEnc->sCmn.indices.signalType = TYPE_UNVOICED; |
135 | 265k | } |
136 | 25.5M | } else { |
137 | 25.5M | silk_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) ); |
138 | 25.5M | psEnc->sCmn.indices.lagIndex = 0; |
139 | 25.5M | psEnc->sCmn.indices.contourIndex = 0; |
140 | 25.5M | psEnc->LTPCorr_Q15 = 0; |
141 | 25.5M | } |
142 | 26.0M | RESTORE_STACK; |
143 | 26.0M | } |