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