Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdint.h>
6 : #include "options.h" /* Compilation switches */
7 : #include "cnst.h" /* Common constants */
8 : #include "rom_com_fx.h" /* Static table prototypes */
9 : #include "rom_com.h" /* Static table prototypes */
10 : #include "rom_enc.h" /* Static table prototypes */
11 : #include "prot_fx.h" /* Function prototypes */
12 : #include "prot_fx_enc.h" /* Function prototypes */
13 :
14 : /*-------------------------------------------------------------------*
15 : * analy_lp_fx()
16 : *
17 : * Perform LP analysis
18 : *
19 : * - autocorrelations + lag windowing
20 : * - Levinson-Durbin algorithm to find A(z)
21 : * - convert A(z) to LSPs
22 : * - find interpolated LSPs and convert back to A(z) for all subframes
23 : * - update LSPs for the next frame
24 : *-------------------------------------------------------------------*/
25 :
26 1297589 : void analy_lp_fx(
27 : const Word16 speech[], /* i :(Q_new) pointer to the speech frame */
28 : const Word16 L_frame, /* i :(q0) length of the frame */
29 : const Word16 L_look, /* i :(q0) look-ahead */
30 : Word32 *ener, /* o :(Q_r) residual energy from Levinson-Durbin */
31 : Word16 A[], /* o :(q14) A(z) filter coefficients */
32 : Word16 epsP_h[], /* o :(high part of epsP(Q_r)) LP analysis residual energies for each iteration */
33 : Word16 epsP_l[], /* o :(low part of epsP(Q_r)) LP analysis residual energies for each iteration */
34 : Word16 lsp_new[], /* o :(q15) current frame LSPs */
35 : Word16 lsp_mid[], /* o :(q15) current mid-frame LSPs */
36 : Word16 lsp_old[], /* i/o:(q15) previous frame unquantized LSPs */
37 : const Word16 Top[2], /* i :(q0) open loop pitch lag */
38 : const Word16 Tnc[2], /* i :(q15) open loop pitch gain */
39 : const Word32 Core_sr, /* i :(q0) Internal core sampling rate */
40 : const Word16 element_mode, /* i : element mode */
41 : const Word16 sec_chan_low_rate, /* i :(q0) flag to signal second channel */
42 : Word16 Q_new, /* i : stores Q for speech */
43 : Word16 *Q_r /*stores q for ener*/
44 : )
45 : {
46 : Word16 r_h[M + 1]; /* Autocorrelations of windowed speech MSB */
47 : Word16 r_l[M + 1]; /* Autocorrelations of windowed speech LSB */
48 : Word32 LepsP[M + 1];
49 1297589 : Word16 i, i_subfr, wind_length = 0;
50 : Word16 *lsp;
51 1297589 : const Word16 *wind = NULL;
52 : const Word16 *pt;
53 : Word16 half_frame;
54 1297589 : move16(); /* wind_length*/
55 :
56 1297589 : IF( EQ_16( L_frame, L_FRAME ) )
57 : {
58 1132084 : wind_length = L_LP;
59 1132084 : move16();
60 1132084 : wind = Assym_window_W16fx; /*q15*/
61 : }
62 : ELSE /* L_frame == L_FRAME16k */
63 : {
64 165505 : wind_length = L_LP_16k;
65 165505 : move16();
66 165505 : wind = assym_window_16k_fx; /*q15*/
67 : }
68 1297589 : lsp = lsp_mid; /* Q15 */
69 1297589 : half_frame = shr( L_frame, 1 );
70 :
71 3892767 : FOR( i_subfr = 0; i_subfr <= 1; i_subfr++ )
72 : {
73 2595178 : pt = speech + sub( add( half_frame, L_look ), wind_length );
74 2595178 : half_frame = shl( half_frame, 1 );
75 :
76 : /* Autocorrelations */
77 2595178 : autocorr_fx( pt, M, r_h, r_l, &Q_r[1 - i_subfr], wind_length, wind, 0, 0 );
78 :
79 2595178 : IF( NE_16( element_mode, EVS_MONO ) )
80 : {
81 : /*if ( r[0] < 100.0f && no_thr == 0 )*/
82 : /*r[0] = 100.0f*/
83 2584878 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( L_Comp( r_h[0], r_l[0] ) /* Q_r[1 - i_subfr]*/, sub( 31, add( Q_r[1 - i_subfr], shl( Q_new, 1 ) ) ), 100 /*q0*/, 31 ), -1 ) )
84 : {
85 : /*Q_min stores min of 24 and the actual Q for r*/
86 237426 : Word16 Q_min = s_min( add( Q_r[1 - i_subfr], shl( Q_new, 1 ) ), 24 ); /* comparing q with 24 because exponent of 100 is 7 so max q should be 24*/
87 237426 : L_Extract( L_shl( 100, Q_min ), &r_h[0], &r_l[0] ); /*extracting high and low components of r[0]*/
88 4036242 : FOR( i = 1; i < 17; i++ )
89 : {
90 3798816 : L_Extract( L_shr( L_Comp( r_h[i], r_l[i] ), sub( add( Q_r[1 - i_subfr], shl( Q_new, 1 ) ), Q_min ) ), &r_h[i], &r_l[i] ); /*scaling all the values to q24*/
91 : }
92 237426 : Q_r[1 - i_subfr] = sub( Q_min, shl( Q_new, 1 ) ); /*updating the q (subtracting shl( Q_new, 1 ) as in later part it is being added-> to maintain q24 )*/
93 237426 : move16();
94 : }
95 : }
96 :
97 : /* Lag windowing */
98 2595178 : adapt_lag_wind( r_h, r_l, M, Top[i_subfr], Tnc[i_subfr], Core_sr );
99 :
100 : /* Levinson-Durbin */
101 2595178 : E_LPC_lev_dur( r_h, r_l, A, LepsP, M, NULL );
102 46713204 : FOR( i = 0; i <= M; i++ )
103 : {
104 44118026 : L_Extract( LepsP[i], &epsP_h[i], &epsP_l[i] );
105 : }
106 : /*Q_r[... might not be needed from external...*/
107 2595178 : Q_r[1 - i_subfr] = add( Q_r[1 - i_subfr], shl( Q_new, 1 ) );
108 2595178 : move16();
109 :
110 : /* Conversion of A(z) to LSPs */
111 2595178 : E_LPC_a_lsp_conversion( A, lsp, lsp_old, M );
112 :
113 2595178 : lsp = lsp_new; /* Q15 */
114 : }
115 1297589 : IF( EQ_16( sec_chan_low_rate, 1 ) )
116 : {
117 : /* LSP interpolation */
118 0 : int_lsp4_ivas_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, -2 );
119 : }
120 : ELSE
121 : {
122 : /* LSP interpolation */
123 1297589 : int_lsp4_ivas_fx( L_frame, lsp_old, lsp_mid, lsp_new, A, M, 0 );
124 : }
125 1297589 : Copy( lsp_new, lsp_old, M ); /* Q15 */
126 1297589 : *ener = L_Comp( epsP_h[M], epsP_l[M] ); /* Q_r */
127 1297589 : move32();
128 :
129 1297589 : return;
130 : }
131 :
132 : /*-------------------------------------------------------------------*
133 : * analy_lp_AMR_WB()
134 : *
135 : * Perform LP analysis for AMR-WB IO mode
136 : *
137 : * - autocorrelations + lag windowing
138 : * - Levinson-Durbin algorithm to find A(z)
139 : * - convert A(z) to ISPs
140 : * - find interpolated ISPs and convert back to A(z) for all subframes
141 : * - update ISPs for the next frame
142 : *-------------------------------------------------------------------*/
143 :
144 0 : void analy_lp_AMR_WB_fx(
145 : const Word16 speech[], /* i : pointer to the speech frame Q_new*/
146 : Word32 *ener, /* o : residual energy from Levinson-Durbin Q_r*/
147 : Word16 A[], /* o : A(z) filter coefficients Q14*/
148 : Word16 epsP_h[], /* o : LP analysis residual energies for each iteration Q_r*/
149 : Word16 epsP_l[], /* o : LP analysis residual energies for each iteration Q_r*/
150 : Word16 isp_new[], /* o : current frame ISPs Q15*/
151 : Word16 isp_old[], /* i/o: previous frame unquantized ISPs Q15*/
152 : Word16 isf_new[], /* o : current frame ISPs Q15*/
153 : Word16 Top, /* i : open loop pitch lag Q0*/
154 : Word16 Tnc, /* i : open loop pitch gain Qx*/
155 : Word16 Q_new,
156 : Word16 *Q_r )
157 : {
158 : Word16 r_h[M + 1]; /* Autocorrelations of windowed speech MSB */
159 : Word16 r_l[M + 1]; /* Autocorrelations of windowed speech LSB */
160 : Word32 LepsP[M + 1];
161 0 : Word16 i, wind_length = 0;
162 : const Word16 *wind;
163 :
164 : /* Initialization */
165 0 : wind_length = L_LP_AMR_WB;
166 0 : move16();
167 0 : wind = hamcos_window_fx;
168 :
169 : /* Autocorrelations */
170 0 : autocorr_fx( speech - L_SUBFR, M, r_h, r_l, &Q_r[0], wind_length, wind, 0, 0 );
171 :
172 : /* Lag windowing */
173 0 : adapt_lag_wind( r_h, r_l, M, Top, Tnc, INT_FS_FX );
174 :
175 : /* Levinson-Durbin */
176 : /*lev_dur( A, r, M, epsP );*/
177 0 : E_LPC_lev_dur( r_h, r_l, A, LepsP, M, NULL );
178 0 : FOR( i = 0; i <= M; i++ )
179 : {
180 0 : L_Extract( LepsP[i], &epsP_h[i], &epsP_l[i] );
181 : }
182 : /*Q_r[... might not be needed from external...*/
183 0 : Q_r[0] = add( Q_r[0], shl( Q_new, 1 ) );
184 0 : move16();
185 :
186 0 : E_LPC_a_lsf_isf_conversion( A, isf_new, stable_ISF_fx, M, 0 );
187 0 : E_LPC_isf_isp_conversion( isf_new, isp_new, M );
188 :
189 : /* ISP interpolation */
190 0 : int_lsp_fx( L_FRAME, isp_old, isp_new, A, M, interpol_isp_amr_wb_fx, 1 );
191 :
192 : /**ener = epsP[M];*/
193 0 : *ener = L_Comp( epsP_h[M], epsP_l[M] ); /* Q_r */
194 0 : move32();
195 :
196 : /* updates */
197 0 : Copy( isp_new, isp_old, M ); /* Q15 */
198 :
199 0 : return;
200 : }
|