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"
7 : #include <assert.h>
8 : //#include "prot_fx.h"
9 : #include "rom_com.h" /* Common constants */
10 : #include "prot_fx.h" /* Function prototypes */
11 : #include "prot_fx_enc.h" /* Function prototypes */
12 : #include "basop_util.h" /* Function prototypes */
13 :
14 : /*-------------------------------------------------------------------*
15 : * gauss_L2_fx:
16 : *
17 : * encode an additional Gaussian excitation for unvoiced subframes and compute
18 : * associated xcorrelations for gains computation
19 : *
20 : * Gaussian excitation is generated by a white noise and shapes it with LPC-derived filter
21 : *-------------------------------------------------------------------*/
22 0 : void gauss_L2_fx(
23 : const Word16 h[], /* i : weighted LP filter impulse response Q14+s */
24 : Word16 code[], /* o : gaussian excitation Q9 */
25 : const Word16 y2[], /* i : zero-memory filtered code. excitation Q9 */
26 : Word16 y11[], /* o : zero-memory filtered gauss. excitation Q9 */
27 : Word32 *gain, /* o : excitation gain Q16 */
28 : ACELP_CbkCorr *g_corr, /*i/o : correlation structure for gain coding */
29 : const Word16 gain_pit, /* i : unquantized gain of code Q14 */
30 : const Word16 tilt_code, /* i : tilt of code Q15 */
31 : const Word16 *Aq, /* i : quantized LPCs Q12 */
32 : const Word16 formant_enh_num, /* i : formant enhancement numerator factor Q15 */
33 : Word16 *seed_acelp, /*i/o : random seed Q0 */
34 : const Word16 shift )
35 : {
36 : Word16 i, tmp16;
37 : Word32 tmp32, tmp32_2;
38 :
39 :
40 0 : assert( gain_pit == 0 );
41 :
42 : /*-----------------------------------------------------------------*
43 : * Find new target for the Gaussian codebook
44 : *-----------------------------------------------------------------*/
45 :
46 : /*Generate white gaussian noise using central limit theorem method (N only 4 as E_util_random is not purely uniform)*/
47 0 : FOR( i = 0; i < L_SUBFR; i++ )
48 : {
49 0 : Random( seed_acelp );
50 0 : tmp32 = L_mac( 0, *seed_acelp, 1 << 9 );
51 :
52 0 : Random( seed_acelp );
53 0 : tmp32 = L_mac( tmp32, *seed_acelp, 1 << 9 );
54 :
55 0 : Random( seed_acelp );
56 0 : code[i] = mac_r( tmp32, *seed_acelp, 1 << 9 );
57 0 : move16();
58 : }
59 :
60 : /*Shape the gaussian excitation*/
61 0 : cb_shape_fx( 1, 0, 0, 1, 0, formant_enh_num, FORMANT_SHARPENING_G2, Aq, code, tilt_code, 0, 1, L_SUBFR );
62 :
63 : /*compute 0s memory weighted synthesis contribution and find gain*/
64 0 : E_UTIL_f_convolve( code, h, y11, L_SUBFR ); /* y11: Q8+shift */
65 0 : Scale_sig( y11, L_SUBFR, sub( 1, shift ) ); /* Q9 */
66 0 : *gain = L_deposit_l( 0 );
67 0 : move32();
68 : /*Update correlations for gains coding */
69 0 : tmp32 = L_shr( 21474836l /*0.01f Q31*/, 31 - 18 ); /* Q18 */
70 0 : tmp32_2 = L_shr( 21474836l /*0.01f Q31*/, 31 - 18 ); /* Q18 */
71 :
72 0 : FOR( i = 0; i < L_SUBFR; i++ )
73 : {
74 0 : tmp32 = L_mac0( tmp32, y11[i], y11[i] ); /* Q18 */
75 0 : tmp32_2 = L_mac0( tmp32_2, y11[i], y2[i] ); /* Q18 */
76 : }
77 :
78 0 : tmp16 = norm_l( tmp32 );
79 0 : g_corr->y1y1 = round_fx_sat( L_shl( tmp32, tmp16 ) );
80 0 : g_corr->y1y1_e = sub( 31 - 18, tmp16 );
81 0 : move16();
82 0 : move16();
83 :
84 0 : tmp16 = norm_l( tmp32_2 );
85 0 : g_corr->y1y2 = round_fx_sat( L_shl( tmp32_2, tmp16 ) );
86 0 : g_corr->y1y2_e = sub( 31 - 18, tmp16 );
87 0 : move16();
88 0 : move16();
89 0 : }
90 :
91 8000 : void gauss_L2_ivas_fx(
92 : const Word16 h[], /* i : weighted LP filter impulse response Q14+s */
93 : Word16 code[], /* o : gaussian excitation Q9 */
94 : const Word16 y2[], /* i : zero-memory filtered code. excitation Q9 */
95 : Word16 y11[], /* o : zero-memory filtered gauss. excitation Q9 */
96 : Word32 *gain, /* o : excitation gain Q16 */
97 : ACELP_CbkCorr *g_corr, /*i/o : correlation structure for gain coding */
98 : const Word16 gain_pit, /* i : unquantized gain of code Q14 */
99 : const Word16 tilt_code, /* i : tilt of code Q15 */
100 : const Word16 *Aq, /* i : quantized LPCs Q12 */
101 : const Word16 formant_enh_num, /* i : formant enhancement numerator factor Q15 */
102 : Word16 *seed_acelp, /*i/o : random seed Q0 */
103 : const Word16 shift )
104 : {
105 : Word16 i, tmp16;
106 : Word32 tmp32, tmp32_2;
107 :
108 :
109 8000 : assert( gain_pit == 0 );
110 :
111 : /*-----------------------------------------------------------------*
112 : * Find new target for the Gaussian codebook
113 : *-----------------------------------------------------------------*/
114 :
115 : /*Generate white gaussian noise using central limit theorem method (N only 4 as E_util_random is not purely uniform)*/
116 520000 : FOR( i = 0; i < L_SUBFR; i++ )
117 : {
118 512000 : Random( seed_acelp );
119 512000 : tmp32 = L_mac( 0, *seed_acelp, 1 << 9 );
120 :
121 512000 : Random( seed_acelp );
122 512000 : tmp32 = L_mac( tmp32, *seed_acelp, 1 << 9 );
123 :
124 512000 : Random( seed_acelp );
125 512000 : code[i] = mac_r( tmp32, *seed_acelp, 1 << 9 );
126 512000 : move16();
127 : }
128 :
129 : /*Shape the gaussian excitation*/
130 8000 : cb_shape_fx( 1, 0, 0, 1, 0, formant_enh_num, FORMANT_SHARPENING_G2, Aq, code, tilt_code, 0, 1, L_SUBFR );
131 :
132 : /*compute 0s memory weighted synthesis contribution and find gain*/
133 8000 : E_UTIL_f_convolve( code, h, y11, L_SUBFR ); /* y11: Q8+shift */
134 8000 : Scale_sig( y11, L_SUBFR, sub( 1, shift ) ); /* Q9 */
135 8000 : *gain = L_deposit_l( 0 );
136 8000 : move32();
137 : /*Update correlations for gains coding */
138 8000 : tmp32 = L_shr( 21474836l /*0.01f Q31*/, 31 - 16 ); /* Q16 */
139 8000 : tmp32_2 = L_shr( 21474836l /*0.01f Q31*/, 31 - 16 ); /* Q16 */
140 520000 : FOR( i = 0; i < L_SUBFR; i++ )
141 : {
142 512000 : tmp16 = shr( y11[i], 1 );
143 512000 : tmp32 = L_mac0( tmp32, tmp16, tmp16 ); /* Q16 */
144 512000 : tmp32_2 = L_mac0( tmp32_2, tmp16, shr( y2[i], 1 ) ); /* Q16 */
145 : }
146 :
147 8000 : tmp16 = norm_l( tmp32 );
148 : // To be checked
149 8000 : g_corr->y1y1 = round_fx_sat( L_shl( tmp32, tmp16 ) );
150 8000 : g_corr->y1y1_e = sub( 31 - 16, tmp16 );
151 8000 : move16();
152 8000 : move16();
153 :
154 8000 : tmp16 = norm_l( tmp32_2 );
155 8000 : g_corr->y1y2 = round_fx_sat( L_shl( tmp32_2, tmp16 ) );
156 8000 : g_corr->y1y2_e = sub( 31 - 16, tmp16 );
157 8000 : move16();
158 8000 : move16();
159 8000 : }
|