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 : #include <stdint.h>
34 : #include "options.h"
35 : #include "ivas_prot_fx.h"
36 : #include "ivas_stat_dec.h"
37 : #include "ivas_cnst.h"
38 : #include "wmc_auto.h"
39 :
40 : /*-------------------------------------------------------------------*
41 : * init_basic_allpass()
42 : *
43 : *
44 : *-------------------------------------------------------------------*/
45 :
46 2850 : void init_basic_allpass_fx(
47 : basic_allpass_t *ap,
48 : const Word32 *gains_fx, /* Q31 */
49 : const Word16 *delays /* Q15 */
50 : )
51 : {
52 : Word16 i, j;
53 :
54 11400 : FOR( i = 0; i < 3; i++ )
55 : {
56 8550 : ap->delays[i] = delays[i]; /* Q0 */
57 8550 : move16();
58 8550 : ap->gains_fx[i] = gains_fx[i]; /* Q31 */
59 8550 : move32();
60 :
61 2197350 : FOR( j = 0; j < STEREO_DFT_ALLPASS_BUFFERLEN; j++ )
62 : {
63 2188800 : ap->buffer_fx[i][j] = 0; /* q_buffer_fx */
64 2188800 : move32();
65 : }
66 8550 : ap->q_buffer_fx = 0;
67 8550 : move16();
68 : }
69 :
70 2850 : ap->pos = 0;
71 2850 : move16();
72 :
73 2850 : return;
74 : }
75 :
76 :
77 : /*-------------------------------------------------------------------*
78 : * filter_with_allpass()
79 : *
80 : *
81 : *-------------------------------------------------------------------*/
82 :
83 97554 : void filter_with_allpass_fx(
84 : const Word32 *sig, /* q_shift */
85 : Word32 *out, /* q_shift */
86 : const Word16 len, /* Q0 */
87 : basic_allpass_t *ap,
88 : Word16 q_shift )
89 : {
90 : Word16 k;
91 : Word16 pos, mask;
92 : Word16 d1, d2, d3;
93 : Word32 P1_fx, P2_fx, P3_fx, P4_fx, P5_fx;
94 : Word32 g1_fx, g2_fx, g3_fx, *D1_fx, *D2_fx, *D3_fx;
95 :
96 97554 : P1_fx = P2_fx = P3_fx = P4_fx = P5_fx = 0;
97 97554 : move32();
98 97554 : move32();
99 97554 : move32();
100 97554 : move32();
101 97554 : move32();
102 97554 : mask = sub( STEREO_DFT_ALLPASS_BUFFERLEN, 1 );
103 97554 : move32();
104 :
105 97554 : pos = ap->pos;
106 97554 : move16();
107 :
108 97554 : g1_fx = ap->gains_fx[0]; /* Q31 */
109 97554 : move32();
110 97554 : g2_fx = ap->gains_fx[1]; /* Q31 */
111 97554 : move32();
112 97554 : g3_fx = ap->gains_fx[2]; /* Q31 */
113 97554 : move32();
114 :
115 97554 : d1 = ap->delays[0]; /* Q0 */
116 97554 : move16();
117 97554 : d2 = ap->delays[1]; /* Q0 */
118 97554 : move16();
119 97554 : d3 = ap->delays[2]; /* Q0 */
120 97554 : move16();
121 :
122 97554 : D1_fx = ap->buffer_fx[0]; /* q_buffer_fx */
123 97554 : move32();
124 97554 : D2_fx = ap->buffer_fx[1]; /* q_buffer_fx */
125 97554 : move32();
126 97554 : D3_fx = ap->buffer_fx[2]; /* q_buffer_fx */
127 97554 : move32();
128 :
129 97554 : IF( NE_16( q_shift, ap->q_buffer_fx ) )
130 : {
131 1641459 : FOR( k = 0; k < (Word16) ( sizeof( ap->buffer_fx[0] ) / sizeof( ap->buffer_fx[0][0] ) ); k++ )
132 : {
133 1635072 : D1_fx[k] = L_shr( D1_fx[k], sub( ap->q_buffer_fx, q_shift ) ); /* q_shift */
134 1635072 : move32();
135 1635072 : D2_fx[k] = L_shr( D2_fx[k], sub( ap->q_buffer_fx, q_shift ) ); /* q_shift */
136 1635072 : move32();
137 1635072 : D3_fx[k] = L_shr( D3_fx[k], sub( ap->q_buffer_fx, q_shift ) ); /* q_shift */
138 1635072 : move32();
139 : }
140 6387 : ap->q_buffer_fx = q_shift;
141 6387 : move16();
142 : }
143 :
144 97554 : Word32 D1_upd = add( pos, d1 ), D2_upd = add( pos, d2 ), D3_upd = add( pos, d3 );
145 :
146 25071378 : FOR( k = 0; k <= mask; k++ )
147 : {
148 24973824 : IF( EQ_32( pos, D1_upd ) )
149 : {
150 97554 : D1_upd = -1;
151 97554 : move32();
152 : }
153 24973824 : IF( EQ_32( pos, D2_upd ) )
154 : {
155 97554 : D2_upd = -1;
156 97554 : move32();
157 : }
158 24973824 : IF( EQ_32( pos, D3_upd ) )
159 : {
160 94587 : D3_upd = -1;
161 94587 : move32();
162 : }
163 :
164 24973824 : P1_fx = L_sub_sat( sig[k], Mpy_32_32( g3_fx, D3_fx[pos] ) ); /* q_shift */
165 24973824 : P2_fx = L_sub_sat( P1_fx, Mpy_32_32( g1_fx, D1_fx[pos] ) ); /* q_shift */
166 24973824 : P3_fx = L_add_sat( D1_fx[pos], L_sub( Mpy_32_32( g1_fx, P2_fx ), Mpy_32_32( g2_fx, D2_fx[pos] ) ) ); /* q_shift */
167 24973824 : P4_fx = L_add_sat( D2_fx[pos], Mpy_32_32( g2_fx, P3_fx ) ); /* q_shift */
168 24973824 : P5_fx = L_add_sat( D3_fx[pos], Mpy_32_32( g3_fx, P1_fx ) ); /* q_shift */
169 24973824 : out[k] = P5_fx; /* could overwrite sig */
170 24973824 : move32();
171 :
172 24973824 : D1_fx[( pos + d1 ) & mask] = P2_fx; /* q_shift */
173 24973824 : move32();
174 24973824 : D2_fx[( pos + d2 ) & mask] = P3_fx; /* q_shift */
175 24973824 : move32();
176 24973824 : D3_fx[( pos + d3 ) & mask] = P4_fx; /* q_shift */
177 24973824 : move32();
178 :
179 24973824 : pos = s_and( add( pos, 1 ), mask );
180 : }
181 :
182 2508498 : FOR( k = mask + 1; k < len; k++ )
183 : {
184 :
185 2410944 : P1_fx = L_sub( sig[k], Mpy_32_32( g3_fx, D3_fx[pos] ) ); /* q_shift */
186 2410944 : P2_fx = L_sub( P1_fx, Mpy_32_32( g1_fx, D1_fx[pos] ) ); /* q_shift */
187 2410944 : P3_fx = L_add( D1_fx[pos], L_sub( Mpy_32_32( g1_fx, P2_fx ), Mpy_32_32( g2_fx, D2_fx[pos] ) ) ); /* q_shift */
188 2410944 : P4_fx = L_add( D2_fx[pos], Mpy_32_32( g2_fx, P3_fx ) ); /* q_shift */
189 2410944 : P5_fx = L_add( D3_fx[pos], Mpy_32_32( g3_fx, P1_fx ) ); /* q_shift */
190 2410944 : out[k] = P5_fx; /* could overwrite sig */
191 2410944 : move32();
192 :
193 2410944 : D1_fx[( pos + d1 ) & mask] = P2_fx; /* q_shift */
194 2410944 : move32();
195 2410944 : D2_fx[( pos + d2 ) & mask] = P3_fx; /* q_shift */
196 2410944 : move32();
197 2410944 : D3_fx[( pos + d3 ) & mask] = P4_fx; /* q_shift */
198 2410944 : move32();
199 :
200 2410944 : pos = s_and( add( pos, 1 ), mask );
201 : }
202 :
203 97554 : ap->pos = pos;
204 97554 : move16();
205 :
206 97554 : return;
207 : }
|