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" /* EV-VBR compilation switches */
7 : #include "prot_fx.h"
8 : #include "basop_util.h"
9 : #include "rom_com.h"
10 :
11 : /*-----------------------------------------------------------------------*
12 : * phase_dispersion:
13 : *
14 : * post-processing to enhance noise at low bit rate.
15 : *-----------------------------------------------------------------------*/
16 :
17 3050 : void phase_dispersion(
18 : const Word32 gain_code, /* i : gain of code 15Q16 */
19 : const Word16 gain_pit, /* i : gain of pitch Q14 */
20 : Word16 code[], /* i/o: code vector */
21 : Word16 *code_exp, /* i/o: exponent of code */
22 : const Word16 mode, /* i : level, 0=hi, 1=lo, 2=off */
23 : Word32 *prev_gain_code, /* i/o: static memory 15Q16 */
24 : Word16 prev_gain_pit[], /* i/o: static memory Q14, size=6 */
25 : Word16 *prev_state, /* i/o: static memory Q0 */
26 : Word16 L_subfr /* i : subframe length [40,64,80]*/
27 : )
28 : {
29 : Word16 i, j, state, scale2;
30 : Word32 x32[2 * L_SUBFR];
31 : Word16 *code_real, *code_imag;
32 : const Word16 *h_real, *h_imag;
33 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
34 3050 : Flag Overflow = 0;
35 : #endif
36 :
37 :
38 3050 : move16();
39 3050 : state = 2;
40 :
41 3050 : if ( LT_16( gain_pit, 14746 /*0.9f Q14*/ ) )
42 : {
43 2128 : move16();
44 2128 : state = 1;
45 : }
46 3050 : if ( LT_16( gain_pit, 9830 /*0.6f Q14*/ ) )
47 : {
48 728 : move16();
49 728 : state = 0;
50 : }
51 :
52 18300 : FOR( i = 5; i > 0; i-- )
53 : {
54 15250 : move16();
55 15250 : prev_gain_pit[i] = prev_gain_pit[i - 1];
56 : }
57 3050 : move16();
58 3050 : prev_gain_pit[0] = gain_pit;
59 :
60 3050 : IF( GT_32( gain_code, L_add_o( *prev_gain_code, L_shl_o( *prev_gain_code, 1, &Overflow ), &Overflow ) ) )
61 : {
62 67 : IF( LT_16( state, 2 ) )
63 : {
64 39 : state = add( state, 1 );
65 : }
66 : }
67 : ELSE
68 : {
69 2983 : j = 0;
70 20881 : FOR( i = 0; i < 6; i++ )
71 : {
72 :
73 17898 : IF( LT_32( prev_gain_pit[i], 9830 /*0.6f Q14*/ ) )
74 : {
75 4316 : j = add( j, 1 );
76 : }
77 : }
78 :
79 2983 : if ( GT_16( j, 2 ) )
80 : {
81 771 : move16();
82 771 : state = 0;
83 : }
84 :
85 2983 : IF( GT_16( sub( state, *prev_state ), 1 ) )
86 : {
87 93 : state = sub( state, 1 );
88 : }
89 : }
90 :
91 3050 : move32();
92 3050 : move16();
93 3050 : *prev_gain_code = gain_code;
94 3050 : *prev_state = state;
95 :
96 : /*-----------------------------------------------------------------*
97 : * circular convolution
98 : *-----------------------------------------------------------------*/
99 :
100 3050 : state = add( state, mode ); /* level of dispersion */
101 3050 : j = *code_exp;
102 3050 : move16();
103 3050 : IF( LT_16( state, 2 ) )
104 : {
105 0 : FOR( i = 0; i < L_subfr; i++ )
106 : {
107 0 : x32[i] = L_deposit_h( code[i] );
108 0 : move32();
109 : }
110 :
111 0 : BASOP_rfft( x32, L_subfr, &j, -1 );
112 :
113 : /* Normalize output data. */
114 0 : scale2 = getScaleFactor32( x32, L_subfr );
115 0 : FOR( i = 0; i < L_subfr / 2 - 1; i++ )
116 : {
117 0 : code[i] = round_fx_sat( L_shl_sat( x32[2 * i], scale2 ) );
118 0 : code[L_subfr - 1 - i] = round_fx_sat( L_shl_sat( x32[2 * i + 3], scale2 ) );
119 : }
120 :
121 0 : code[L_subfr / 2 - 1] = round_fx_sat( L_shl_sat( x32[L_subfr - 2], scale2 ) );
122 0 : code[L_subfr / 2] = round_fx_sat( L_shl_sat( x32[1], scale2 ) );
123 :
124 0 : j = sub( j, scale2 );
125 :
126 0 : h_real = low_H16k;
127 0 : move16();
128 0 : if ( LE_16( L_subfr, 64 ) )
129 : {
130 0 : h_real = low_H;
131 0 : move16();
132 : }
133 0 : IF( EQ_16( state, 1 ) )
134 : {
135 0 : h_real = mid_H16k;
136 0 : move16();
137 0 : if ( LE_16( L_subfr, 64 ) )
138 : {
139 0 : h_real = mid_H;
140 0 : move16();
141 : }
142 : }
143 0 : h_imag = h_real + L_subfr - 1;
144 0 : move16();
145 :
146 0 : code_real = &code[0];
147 0 : code_imag = &code[L_subfr - 1];
148 :
149 0 : x32[0] = L_mult( *code_real++, *h_real++ );
150 0 : move32();
151 0 : FOR( i = 1; i < L_subfr / 2; i++ )
152 : {
153 0 : x32[2 * i] = L_msu( L_mult( *code_real, *h_real ), *code_imag, *h_imag );
154 0 : move32();
155 0 : x32[2 * i + 1] = L_mac( L_mult( *code_real++, *h_imag-- ), *code_imag--, *h_real++ );
156 0 : move32();
157 : }
158 0 : x32[1] = L_mult( *code_real++, *h_real++ );
159 0 : move32();
160 :
161 : /* low_H and mid_H are in Q14 format, thus account that here. */
162 0 : j = add( j, 1 );
163 :
164 0 : BASOP_rfft( x32, L_subfr, &j, 1 );
165 0 : scale2 = getScaleFactor32( x32, L_subfr );
166 0 : FOR( i = 0; i < L_subfr; i++ )
167 : {
168 0 : code[i] = round_fx_o( L_shl_o( x32[i], scale2, &Overflow ), &Overflow );
169 0 : move16();
170 : }
171 0 : j = sub( j, scale2 );
172 : }
173 :
174 : /* Store exponent of code */
175 3050 : move16();
176 3050 : *code_exp = j;
177 3050 : }
|