Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : /*====================================================================================
34 : EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
35 : ====================================================================================*/
36 :
37 : #include <stdint.h>
38 : #include "options.h"
39 : #include <math.h>
40 : #include "cnst.h"
41 : #include "prot_fx.h"
42 : #include "rom_com.h"
43 : #include "wmc_auto.h"
44 :
45 :
46 : /* IVAS 32-bit variant */
47 117074 : void Interpolate_allpass_steep_fx32(
48 : const Word32 *in_fx, /* i : input array of size N Qx */
49 : Word32 *mem_fx, /* i/o: memory Qx */
50 : const Word16 N, /* i : number of input samples */
51 : Word32 *out_fx /* o : output array of size 2*N Qx */
52 : )
53 : {
54 : Word16 n, k;
55 : Word32 temp_fx[ALLPASSSECTIONS_STEEP - 1];
56 :
57 : /* upper allpass filter chain */
58 35793394 : FOR( k = 0; k < N; k++ )
59 : {
60 35676320 : temp_fx[0] = Madd_32_16( mem_fx[0], in_fx[k], AP2_STEEP_FX[0] ); // Qx
61 35676320 : move32();
62 35676320 : mem_fx[0] = Msub_32_16( in_fx[k], temp_fx[0], AP2_STEEP_FX[0] ); // Qx
63 35676320 : move32();
64 :
65 : /* for better performance, unroll this loop */
66 71352640 : FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ )
67 : {
68 35676320 : temp_fx[n] = Madd_32_16( mem_fx[n], temp_fx[n - 1], AP2_STEEP_FX[n] ); // Qx
69 35676320 : move32();
70 35676320 : mem_fx[n] = Msub_32_16( temp_fx[n - 1], temp_fx[n], AP2_STEEP_FX[n] ); // Qx
71 35676320 : move32();
72 : }
73 :
74 35676320 : out_fx[2 * k + 1] = Madd_32_16( mem_fx[ALLPASSSECTIONS_STEEP - 1], temp_fx[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
75 35676320 : move32();
76 35676320 : mem_fx[ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp_fx[ALLPASSSECTIONS_STEEP - 2], out_fx[2 * k + 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
77 35676320 : move32();
78 : }
79 :
80 : /* lower allpass filter chain */
81 35793394 : FOR( k = 0; k < N; k++ )
82 : {
83 35676320 : temp_fx[0] = Madd_32_16( mem_fx[ALLPASSSECTIONS_STEEP], in_fx[k], AP1_STEEP_FX[0] ); // Qx
84 35676320 : move32();
85 35676320 : mem_fx[ALLPASSSECTIONS_STEEP] = Msub_32_16( in_fx[k], temp_fx[0], AP1_STEEP_FX[0] ); // Qx
86 35676320 : move32();
87 :
88 : /* for better performance, unroll this loop */
89 71352640 : FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ )
90 : {
91 35676320 : temp_fx[n] = Madd_32_16( mem_fx[ALLPASSSECTIONS_STEEP + n], temp_fx[n - 1], AP1_STEEP_FX[n] ); // Qx
92 35676320 : move32();
93 35676320 : mem_fx[ALLPASSSECTIONS_STEEP + n] = Msub_32_16( temp_fx[n - 1], temp_fx[n], AP1_STEEP_FX[n] ); // Qx
94 35676320 : move32();
95 : }
96 :
97 35676320 : out_fx[2 * k] = Madd_32_16( mem_fx[2 * ALLPASSSECTIONS_STEEP - 1], temp_fx[ALLPASSSECTIONS_STEEP - 2], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
98 35676320 : move32();
99 35676320 : mem_fx[2 * ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp_fx[ALLPASSSECTIONS_STEEP - 2], out_fx[2 * k], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
100 35676320 : move32();
101 : }
102 :
103 117074 : return;
104 : }
105 :
106 : /* IVAS 32-bit variant */
107 4404 : void Decimate_allpass_steep_fx32(
108 : const Word32 *in, /* i : input array of size N Qx */
109 : Word32 *mem, /* i/o: memory Qx */
110 : const Word16 N, /* i : number of input samples */
111 : Word32 *out /* o : output array of size N/2 Qx */
112 : )
113 : {
114 : Word16 n, k;
115 : Word32 temp[ALLPASSSECTIONS_STEEP];
116 :
117 : /* upper allpass filter chain */
118 1413684 : FOR( k = 0; k < N / 2; k++ )
119 : {
120 : #ifdef OPT_STEREO_32KBPS_V1
121 1409280 : temp[0] = Madd_32_16( mem[0], in[2 * k], AP1_STEEP_FX[0] ); // Qx
122 1409280 : move32();
123 1409280 : mem[0] = Msub_32_16( in[2 * k], temp[0], AP1_STEEP_FX[0] ); // Qx
124 1409280 : move32();
125 :
126 1409280 : temp[1] = Madd_32_16( mem[1], temp[0], AP1_STEEP_FX[1] ); // Qx
127 1409280 : move32();
128 1409280 : mem[1] = Msub_32_16( temp[0], temp[1], AP1_STEEP_FX[1] ); // Qx
129 1409280 : move32();
130 :
131 1409280 : out[k] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP - 1], temp[ALLPASSSECTIONS_STEEP - 2], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
132 1409280 : move32();
133 1409280 : mem[ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp[ALLPASSSECTIONS_STEEP - 2], out[k], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
134 1409280 : move32();
135 : #else /* OPT_STEREO_32KBPS_V1 */
136 : temp[0] = L_add( mem[0], Mpy_32_16_1( in[2 * k], AP1_STEEP_FX[0] ) ); // Qx
137 : move32();
138 : mem[0] = L_sub( in[2 * k], Mpy_32_16_1( temp[0], AP1_STEEP_FX[0] ) ); // Qx
139 : move32();
140 :
141 : temp[1] = L_add( mem[1], Mpy_32_16_1( temp[0], AP1_STEEP_FX[1] ) ); // Qx
142 : move32();
143 : mem[1] = L_sub( temp[0], Mpy_32_16_1( temp[1], AP1_STEEP_FX[1] ) ); // Qx
144 : move32();
145 :
146 : out[k] = L_add( mem[ALLPASSSECTIONS_STEEP - 1], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 2], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx
147 : move32();
148 : mem[ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( out[k], AP1_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx
149 : move32();
150 : #endif /* OPT_STEREO_32KBPS_V1 */
151 : }
152 :
153 : /* lower allpass filter chain */
154 : #ifdef OPT_STEREO_32KBPS_V1
155 4404 : temp[0] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP], mem[2 * ALLPASSSECTIONS_STEEP], AP2_STEEP_FX[0] ); // Qx
156 4404 : move32();
157 4404 : mem[ALLPASSSECTIONS_STEEP] = Msub_32_16( mem[2 * ALLPASSSECTIONS_STEEP], temp[0], AP2_STEEP_FX[0] ); // Qx
158 4404 : move32();
159 : #else /* OPT_STEREO_32KBPS_V1 */
160 : temp[0] = L_add( mem[ALLPASSSECTIONS_STEEP], Mpy_32_16_1( mem[2 * ALLPASSSECTIONS_STEEP], AP2_STEEP_FX[0] ) ); // Qx
161 : move32();
162 : mem[ALLPASSSECTIONS_STEEP] = L_sub( mem[2 * ALLPASSSECTIONS_STEEP], Mpy_32_16_1( temp[0], AP2_STEEP_FX[0] ) ); // Qx
163 : move32();
164 : #endif /* OPT_STEREO_32KBPS_V1 */
165 :
166 : /* for better performance, unroll this loop */
167 8808 : FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ )
168 : {
169 : #ifdef OPT_STEREO_32KBPS_V1
170 4404 : temp[n] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP + n], temp[n - 1], AP2_STEEP_FX[n] ); // Qx
171 4404 : move32();
172 4404 : mem[ALLPASSSECTIONS_STEEP + 1] = Msub_32_16( temp[n - 1], temp[n], AP2_STEEP_FX[n] ); // Qx
173 4404 : move32();
174 : #else /* OPT_STEREO_32KBPS_V1 */
175 : temp[n] = L_add( mem[ALLPASSSECTIONS_STEEP + n], Mpy_32_16_1( temp[n - 1], AP2_STEEP_FX[n] ) ); // Qx
176 : move32();
177 : /*if ( fabs( temp[n] ) < 1e-12 )
178 : {
179 : temp[n] = sign( temp[n] ) * 1e-12f;
180 : }*/
181 : mem[ALLPASSSECTIONS_STEEP + 1] = L_sub( temp[n - 1], Mpy_32_16_1( temp[n], AP2_STEEP_FX[n] ) ); // Qx
182 : move32();
183 : #endif /* OPT_STEREO_32KBPS_V1 */
184 : }
185 :
186 : #ifdef OPT_STEREO_32KBPS_V1
187 4404 : temp[ALLPASSSECTIONS_STEEP - 1] = Madd_32_16( mem[2 * ALLPASSSECTIONS_STEEP - 1], temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
188 4404 : move32();
189 :
190 4404 : mem[2 * ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp[ALLPASSSECTIONS_STEEP - 2], temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
191 4404 : move32();
192 : #else /* OPT_STEREO_32KBPS_V1 */
193 : temp[ALLPASSSECTIONS_STEEP - 1] = L_add( mem[2 * ALLPASSSECTIONS_STEEP - 1], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx
194 : move32();
195 :
196 : mem[2 * ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx
197 : move32();
198 : #endif /* OPT_STEREO_32KBPS_V1 */
199 4404 : out[0] = W_round48_L( W_mac_32_16( W_mult_32_16( out[0], 16384 /*0.5 in Q15*/ ), temp[ALLPASSSECTIONS_STEEP - 1], 16384 /*0.5 in Q15*/ ) ); // Qx
200 4404 : move32();
201 :
202 1409280 : FOR( k = 1; k < N / 2; k++ )
203 : {
204 : #ifdef OPT_STEREO_32KBPS_V1
205 1404876 : temp[0] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP], in[2 * k - 1], AP2_STEEP_FX[0] ); // Qx
206 1404876 : move32();
207 1404876 : mem[ALLPASSSECTIONS_STEEP] = Msub_32_16( in[2 * k - 1], temp[0], AP2_STEEP_FX[0] ); // Qx
208 1404876 : move32();
209 : #else /* OPT_STEREO_32KBPS_V1 */
210 : temp[0] = L_add( mem[ALLPASSSECTIONS_STEEP], Mpy_32_16_1( in[sub( shl( k, 1 ), 1 )], AP2_STEEP_FX[0] ) ); // Qx
211 : move32();
212 : mem[ALLPASSSECTIONS_STEEP] = L_sub( in[sub( shl( k, 1 ), 1 )], Mpy_32_16_1( temp[0], AP2_STEEP_FX[0] ) ); // Qx
213 : move32();
214 : #endif /* OPT_STEREO_32KBPS_V1 */
215 :
216 : /* for better performance, unroll this loop */
217 2809752 : FOR( n = 1; n < ALLPASSSECTIONS_STEEP - 1; n++ )
218 : {
219 : #ifdef OPT_STEREO_32KBPS_V1
220 1404876 : temp[n] = Madd_32_16( mem[ALLPASSSECTIONS_STEEP + n], temp[n - 1], AP2_STEEP_FX[n] ); // Qx
221 1404876 : move32();
222 1404876 : mem[ALLPASSSECTIONS_STEEP + n] = Msub_32_16( temp[n - 1], temp[n], AP2_STEEP_FX[n] ); // Qx
223 1404876 : move32();
224 : #else /* OPT_STEREO_32KBPS_V1 */
225 : temp[n] = L_add( mem[ALLPASSSECTIONS_STEEP + n], Mpy_32_16_1( temp[n - 1], AP2_STEEP_FX[n] ) ); // Qx
226 : move32();
227 : /*if ( fabs( temp[n] ) < 1e-12 )
228 : {
229 : temp[n] = sign( temp[n] ) * 1e-12f;
230 : }*/
231 : mem[ALLPASSSECTIONS_STEEP + n] = L_sub( temp[n - 1], Mpy_32_16_1( temp[n], AP2_STEEP_FX[n] ) ); // Qx
232 : move32();
233 : #endif /* OPT_STEREO_32KBPS_V1 */
234 : }
235 :
236 : #ifdef OPT_STEREO_32KBPS_V1
237 1404876 : temp[ALLPASSSECTIONS_STEEP - 1] = Madd_32_16( mem[2 * ALLPASSSECTIONS_STEEP - 1], temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
238 1404876 : move32();
239 1404876 : mem[2 * ALLPASSSECTIONS_STEEP - 1] = Msub_32_16( temp[ALLPASSSECTIONS_STEEP - 2], temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ); // Qx
240 1404876 : move32();
241 : #else /* OPT_STEREO_32KBPS_V1 */
242 : temp[ALLPASSSECTIONS_STEEP - 1] = L_add( mem[2 * ALLPASSSECTIONS_STEEP - 1], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 2], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx
243 : move32();
244 : mem[2 * ALLPASSSECTIONS_STEEP - 1] = L_sub( temp[ALLPASSSECTIONS_STEEP - 2], Mpy_32_16_1( temp[ALLPASSSECTIONS_STEEP - 1], AP2_STEEP_FX[ALLPASSSECTIONS_STEEP - 1] ) ); // Qx
245 : move32();
246 : #endif /* OPT_STEREO_32KBPS_V1 */
247 1404876 : out[k] = W_round48_L( W_mac_32_16( W_mult_32_16( out[k], 16384 /*0.5 in Q15*/ ), temp[ALLPASSSECTIONS_STEEP - 1], 16384 /*0.5 in Q15*/ ) ); // Qx
248 1404876 : move32();
249 : }
250 :
251 : /* z^(-1) */
252 4404 : mem[2 * ALLPASSSECTIONS_STEEP] = in[N - 1];
253 4404 : move32();
254 :
255 4404 : return;
256 : }
257 :
258 : /* IVAS 32-bit variant */
259 80044 : void interpolate_3_over_2_allpass_fx32(
260 : const Word32 *input, /* i : input signal Qx*/
261 : const Word16 len, /* i : number of input samples */
262 : Word32 *out, /* o : output signal Qx*/
263 : Word32 *mem /* i/o: memory Qx*/
264 : )
265 : {
266 : Word16 i, loop_len;
267 : Word32 Vu[2], Vm[2], Vl[2]; /* Outputs of three cascaded allpass stages (upper, middle, and lower) */
268 : Word32 out1_buff[L_FRAME32k * 3];
269 : Word32 *out1;
270 : Word32 mem_temp;
271 80044 : const Word16 *filt_coeff = allpass_poles_3_ov_2; // Q15
272 :
273 80044 : out1 = out1_buff;
274 :
275 49565144 : FOR( i = 0; i < len; i++ )
276 : {
277 : /* Upper branch */
278 : #ifdef OPT_STEREO_32KBPS_V1
279 49485100 : Vu[0] = Madd_32_16( mem[0], L_sub( input[i], mem[1] ), filt_coeff[0] ); // Qx + Q15 - Q15 -> Qx
280 49485100 : move32();
281 49485100 : Vu[1] = Madd_32_16( mem[1], L_sub( Vu[0], mem[2] ), filt_coeff[1] ); // Qx + Q15 - Q15 -> Qx
282 49485100 : move32();
283 49485100 : mem[3] = Madd_32_16( mem[2], L_sub( Vu[1], mem[3] ), filt_coeff[2] ); // Qx + Q15 - Q15 -> Qx
284 49485100 : move32();
285 : #else /* OPT_STEREO_32KBPS_V1 */
286 : Vu[0] = L_add( mem[0], Mpy_32_16_1( L_sub( input[i], mem[1] ), filt_coeff[0] ) ); // Qx + Q15 - Q15 -> Qx
287 : move32();
288 : Vu[1] = L_add( mem[1], Mpy_32_16_1( L_sub( Vu[0], mem[2] ), filt_coeff[1] ) ); // Qx + Q15 - Q15 -> Qx
289 : move32();
290 : mem[3] = L_add( mem[2], Mpy_32_16_1( L_sub( Vu[1], mem[3] ), filt_coeff[2] ) ); // Qx + Q15 - Q15 -> Qx
291 : move32();
292 : #endif /* OPT_STEREO_32KBPS_V1 */
293 :
294 49485100 : mem[1] = Vu[0]; // Qx
295 49485100 : move32();
296 49485100 : mem[2] = Vu[1]; // Qx
297 49485100 : move32();
298 49485100 : *out1++ = mem[3]; // Qx
299 49485100 : move32();
300 :
301 : /* Middle branch */
302 : #ifdef OPT_STEREO_32KBPS_V1
303 49485100 : Vm[0] = Madd_32_16( mem[0], L_sub( input[i], mem[4] ), filt_coeff[3] ); // Qx + Q15 - Q15 -> Qx
304 49485100 : move32();
305 49485100 : Vm[1] = Madd_32_16( mem[4], L_sub( Vm[0], mem[5] ), filt_coeff[4] ); // Qx + Q15 - Q15 -> Qx
306 49485100 : move32();
307 49485100 : mem[6] = Madd_32_16( mem[5], L_sub( Vm[1], mem[6] ), filt_coeff[5] ); // Qx + Q15 - Q15 -> Qx
308 49485100 : move32();
309 : #else /* OPT_STEREO_32KBPS_V1 */
310 : Vm[0] = L_add( mem[0], Mpy_32_16_1( L_sub( input[i], mem[4] ), filt_coeff[3] ) ); // Qx + Q15 - Q15 -> Qx
311 : move32();
312 : Vm[1] = L_add( mem[4], Mpy_32_16_1( L_sub( Vm[0], mem[5] ), filt_coeff[4] ) ); // Qx + Q15 - Q15 -> Qx
313 : move32();
314 : mem[6] = L_add( mem[5], Mpy_32_16_1( L_sub( Vm[1], mem[6] ), filt_coeff[5] ) ); // Qx + Q15 - Q15 -> Qx
315 : move32();
316 : #endif /* OPT_STEREO_32KBPS_V1 */
317 :
318 49485100 : mem[4] = Vm[0]; // Qx
319 49485100 : move32();
320 49485100 : mem[5] = Vm[1]; // Qx
321 49485100 : move32();
322 49485100 : *out1++ = mem[6]; // Qx
323 49485100 : move32();
324 :
325 : /* Lower branch */
326 : #ifdef OPT_STEREO_32KBPS_V1
327 49485100 : Vl[0] = Madd_32_16( mem[0], L_sub( input[i], mem[7] ), filt_coeff[6] ); // Qx + Q15 - Q15 -> Qx
328 49485100 : move32();
329 49485100 : Vl[1] = Madd_32_16( mem[7], L_sub( Vl[0], mem[8] ), filt_coeff[7] ); // Qx + Q15 - Q15 -> Qx
330 49485100 : move32();
331 49485100 : mem[9] = Madd_32_16( mem[8], L_sub( Vl[1], mem[9] ), filt_coeff[8] ); // Qx + Q15 - Q15 -> Qx
332 49485100 : move32();
333 : #else /* OPT_STEREO_32KBPS_V1 */
334 : Vl[0] = L_add( mem[0], Mpy_32_16_1( L_sub( input[i], mem[7] ), filt_coeff[6] ) ); // Qx + Q15 - Q15 -> Qx
335 : move32();
336 : Vl[1] = L_add( mem[7], Mpy_32_16_1( L_sub( Vl[0], mem[8] ), filt_coeff[7] ) ); // Qx + Q15 - Q15 -> Qx
337 : move32();
338 : mem[9] = L_add( mem[8], Mpy_32_16_1( L_sub( Vl[1], mem[9] ), filt_coeff[8] ) ); // Qx + Q15 - Q15 -> Qx
339 : move32();
340 : #endif /* OPT_STEREO_32KBPS_V1 */
341 :
342 49485100 : mem[0] = input[i]; // Qx
343 49485100 : move32();
344 49485100 : mem[7] = Vl[0]; // Qx
345 49485100 : move32();
346 49485100 : mem[8] = Vl[1]; // Qx
347 49485100 : move32();
348 49485100 : *out1++ = mem[9]; // Qx
349 49485100 : move32();
350 : }
351 :
352 80044 : loop_len = shr( i_mult( len, 3 ), 1 );
353 :
354 : /*decimate by 2 and LPF*/
355 74307694 : FOR( i = 0; i < loop_len; i++ )
356 : {
357 74227650 : mem_temp = out1_buff[2 * i];
358 74227650 : move32();
359 : #ifdef OPT_STEREO_32KBPS_V1
360 74227650 : out[i] = Madd_32_16( Mpy_32_16_1( L_add( mem_temp, mem[10] ), 1550 ), L_add( mem[11], mem[14] ), -4965 ); // Qx + Q15 - Q15 -> Qx
361 : // 0.0473147f in Q15 -> 1550, -0.151521f in Q15 -> -4965
362 74227650 : out[i] = Madd_32_16( out[i], L_add( mem[12], mem[13] ), 20125 );
363 : // 0.614152f in Q15 -> 20125
364 : #else /* OPT_STEREO_32KBPS_V1 */
365 : out[i] = L_add( Mpy_32_16_1( L_add( mem_temp, mem[10] ), 1550 ), Mpy_32_16_1( L_add( mem[11], mem[14] ), -4965 ) ); // Qx + Q15 - Q15 -> Qx
366 : // 0.0473147f in Q15 -> 1550, -0.151521f in Q15 -> -4965
367 : out[i] = L_add( out[i], Mpy_32_16_1( L_add( mem[12], mem[13] ), 20125 ) );
368 : // 0.614152f in Q15 -> 20125
369 : #endif /* OPT_STEREO_32KBPS_V1 */
370 74227650 : mem[10] = mem[11]; // Qx
371 74227650 : move32();
372 74227650 : mem[11] = mem[12]; // Qx
373 74227650 : move32();
374 74227650 : mem[12] = mem[13]; // Qx
375 74227650 : move32();
376 74227650 : mem[13] = mem[14]; // Qx
377 74227650 : move32();
378 74227650 : mem[14] = mem_temp; // Qx
379 74227650 : move32();
380 : }
381 :
382 80044 : return;
383 : }
384 :
385 : /* IVAS 32-bit variant */
386 43 : void interpolate_3_over_1_allpass_fx32(
387 : const Word32 *input, /* i : input signal Qx */
388 : const Word16 len, /* i : number of input samples */
389 : Word32 *out, /* o : output signal */
390 : Word32 *mem /* i/o: memory */
391 : )
392 : {
393 : Word16 i, tmp16;
394 : Word32 Vu[2], Vm[2], Vl[2]; /* Outputs of three cascaded allpass stages (upper, middle, and lower) */
395 : Word32 *out1;
396 : Word32 mem_temp;
397 43 : const Word16 *filt_coeff = allpass_poles_3_ov_2; // Qx
398 :
399 43 : out1 = &out[0];
400 :
401 13803 : FOR( i = 0; i < len; i++ )
402 : {
403 : /* Upper branch */
404 13760 : Vu[0] = L_add_sat( mem[0], Mpy_32_16_1( L_sub( input[i], mem[1] ), filt_coeff[0] ) ); // Qx
405 13760 : move32();
406 13760 : Vu[1] = L_add_sat( mem[1], Mpy_32_16_1( L_sub( Vu[0], mem[2] ), filt_coeff[1] ) ); // Qx
407 13760 : move32();
408 13760 : mem[3] = L_add_sat( mem[2], Mpy_32_16_1( L_sub( Vu[1], mem[3] ), filt_coeff[2] ) ); // Qx
409 13760 : move32();
410 :
411 13760 : mem[1] = Vu[0]; // Qx
412 13760 : move32();
413 13760 : mem[2] = Vu[1]; // Qx
414 13760 : move32();
415 13760 : *out1++ = mem[3]; // Qx
416 13760 : move32();
417 :
418 : /* Middle branch */
419 13760 : Vm[0] = L_add_sat( mem[0], Mpy_32_16_1( L_sub( input[i], mem[4] ), filt_coeff[3] ) ); // Qx
420 13760 : move32();
421 13760 : Vm[1] = L_add_sat( mem[4], Mpy_32_16_1( L_sub( Vm[0], mem[5] ), filt_coeff[4] ) ); // Qx
422 13760 : move32();
423 13760 : mem[6] = L_add_sat( mem[5], Mpy_32_16_1( L_sub( Vm[1], mem[6] ), filt_coeff[5] ) ); // Qx
424 13760 : move32();
425 :
426 13760 : mem[4] = Vm[0]; // Qx
427 13760 : move32();
428 13760 : mem[5] = Vm[1]; // Qx
429 13760 : move32();
430 13760 : *out1++ = mem[6]; // Qx
431 13760 : move32();
432 :
433 : /* Lower branch */
434 13760 : Vl[0] = L_add_sat( mem[0], Mpy_32_16_1( L_sub( input[i], mem[7] ), filt_coeff[6] ) ); // Qx
435 13760 : move32();
436 13760 : Vl[1] = L_add_sat( mem[7], Mpy_32_16_1( L_sub( Vl[0], mem[8] ), filt_coeff[7] ) ); // Qx
437 13760 : move32();
438 13760 : mem[9] = L_add_sat( mem[8], Mpy_32_16_1( L_sub( Vl[1], mem[9] ), filt_coeff[8] ) ); // Qx
439 13760 : move32();
440 :
441 13760 : mem[0] = input[i]; // Qx
442 13760 : move32();
443 13760 : mem[7] = Vl[0]; // Qx
444 13760 : move32();
445 13760 : mem[8] = Vl[1]; // Qx
446 13760 : move32();
447 13760 : *out1++ = mem[9]; // Qx
448 13760 : move32();
449 : }
450 :
451 : /*LPF*/
452 43 : tmp16 = imult1616( len, 3 );
453 41323 : FOR( i = 0; i < tmp16; i++ )
454 : {
455 41280 : mem_temp = out[i]; // Qx
456 41280 : move32();
457 41280 : out[i] = L_sub_sat( Mpy_32_16_1( L_add_sat( mem[12], mem[11] ), 18768 ), Mpy_32_16_1( L_add_sat( mem_temp, mem[10] ), 2424 ) ); // Qx
458 : // 0.572769 in Q15 -> 18768, 0.074005 in Q15 -> 2424
459 41280 : move32();
460 41280 : mem[10] = mem[11]; // Qx
461 41280 : move32();
462 41280 : mem[11] = mem[12]; // Qx
463 41280 : move32();
464 41280 : mem[12] = mem_temp; // Qx
465 41280 : move32();
466 : }
467 :
468 43 : return;
469 : }
|