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 2724 : 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 10896 : FOR( i = 0; i < 3; i++ )
55 : {
56 8172 : ap->delays[i] = delays[i]; /* Q0 */
57 8172 : move16();
58 8172 : ap->gains_fx[i] = gains_fx[i]; /* Q31 */
59 8172 : move32();
60 :
61 2100204 : FOR( j = 0; j < STEREO_DFT_ALLPASS_BUFFERLEN; j++ )
62 : {
63 2092032 : ap->buffer_fx[i][j] = 0; /* q_buffer_fx */
64 2092032 : move32();
65 : }
66 8172 : ap->q_buffer_fx = 0;
67 8172 : move16();
68 : }
69 :
70 2724 : ap->pos = 0;
71 2724 : move16();
72 :
73 2724 : return;
74 : }
75 :
76 :
77 : /*-------------------------------------------------------------------*
78 : * filter_with_allpass()
79 : *
80 : *
81 : *-------------------------------------------------------------------*/
82 :
83 96492 : 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 96492 : P1_fx = P2_fx = P3_fx = P4_fx = P5_fx = 0;
97 96492 : move32();
98 96492 : move32();
99 96492 : move32();
100 96492 : move32();
101 96492 : move32();
102 96492 : mask = sub( STEREO_DFT_ALLPASS_BUFFERLEN, 1 );
103 96492 : move32();
104 :
105 96492 : pos = ap->pos;
106 96492 : move16();
107 :
108 96492 : g1_fx = ap->gains_fx[0]; /* Q31 */
109 96492 : move32();
110 96492 : g2_fx = ap->gains_fx[1]; /* Q31 */
111 96492 : move32();
112 96492 : g3_fx = ap->gains_fx[2]; /* Q31 */
113 96492 : move32();
114 :
115 96492 : d1 = ap->delays[0]; /* Q0 */
116 96492 : move16();
117 96492 : d2 = ap->delays[1]; /* Q0 */
118 96492 : move16();
119 96492 : d3 = ap->delays[2]; /* Q0 */
120 96492 : move16();
121 :
122 96492 : D1_fx = ap->buffer_fx[0]; /* q_buffer_fx */
123 96492 : move32();
124 96492 : D2_fx = ap->buffer_fx[1]; /* q_buffer_fx */
125 96492 : move32();
126 96492 : D3_fx = ap->buffer_fx[2]; /* q_buffer_fx */
127 96492 : move32();
128 :
129 96492 : IF( NE_16( q_shift, ap->q_buffer_fx ) )
130 : {
131 1610619 : FOR( k = 0; k < (Word16) ( sizeof( ap->buffer_fx[0] ) / sizeof( ap->buffer_fx[0][0] ) ); k++ )
132 : {
133 1604352 : D1_fx[k] = L_shr( D1_fx[k], sub( ap->q_buffer_fx, q_shift ) ); /* q_shift */
134 1604352 : move32();
135 1604352 : D2_fx[k] = L_shr( D2_fx[k], sub( ap->q_buffer_fx, q_shift ) ); /* q_shift */
136 1604352 : move32();
137 1604352 : D3_fx[k] = L_shr( D3_fx[k], sub( ap->q_buffer_fx, q_shift ) ); /* q_shift */
138 1604352 : move32();
139 : }
140 6267 : ap->q_buffer_fx = q_shift;
141 6267 : move16();
142 : }
143 :
144 96492 : Word32 D1_upd = add( pos, d1 ), D2_upd = add( pos, d2 ), D3_upd = add( pos, d3 );
145 :
146 24798444 : FOR( k = 0; k <= mask; k++ )
147 : {
148 24701952 : IF( EQ_32( pos, D1_upd ) )
149 : {
150 96492 : D1_upd = -1;
151 96492 : move32();
152 : }
153 24701952 : IF( EQ_32( pos, D2_upd ) )
154 : {
155 96492 : D2_upd = -1;
156 96492 : move32();
157 : }
158 24701952 : IF( EQ_32( pos, D3_upd ) )
159 : {
160 93550 : D3_upd = -1;
161 93550 : move32();
162 : }
163 :
164 24701952 : P1_fx = L_sub_sat( sig[k], Mpy_32_32( g3_fx, D3_fx[pos] ) ); /* q_shift */
165 24701952 : P2_fx = L_sub_sat( P1_fx, Mpy_32_32( g1_fx, D1_fx[pos] ) ); /* q_shift */
166 24701952 : 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 24701952 : P4_fx = L_add_sat( D2_fx[pos], Mpy_32_32( g2_fx, P3_fx ) ); /* q_shift */
168 24701952 : P5_fx = L_add_sat( D3_fx[pos], Mpy_32_32( g3_fx, P1_fx ) ); /* q_shift */
169 24701952 : out[k] = P5_fx; /* could overwrite sig */
170 24701952 : move32();
171 :
172 24701952 : D1_fx[( pos + d1 ) & mask] = P2_fx; /* q_shift */
173 24701952 : move32();
174 24701952 : D2_fx[( pos + d2 ) & mask] = P3_fx; /* q_shift */
175 24701952 : move32();
176 24701952 : D3_fx[( pos + d3 ) & mask] = P4_fx; /* q_shift */
177 24701952 : move32();
178 :
179 24701952 : pos = s_and( add( pos, 1 ), mask );
180 : }
181 :
182 2479212 : FOR( k = mask + 1; k < len; k++ )
183 : {
184 :
185 2382720 : P1_fx = L_sub( sig[k], Mpy_32_32( g3_fx, D3_fx[pos] ) ); /* q_shift */
186 2382720 : P2_fx = L_sub( P1_fx, Mpy_32_32( g1_fx, D1_fx[pos] ) ); /* q_shift */
187 2382720 : 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 2382720 : P4_fx = L_add( D2_fx[pos], Mpy_32_32( g2_fx, P3_fx ) ); /* q_shift */
189 2382720 : P5_fx = L_add( D3_fx[pos], Mpy_32_32( g3_fx, P1_fx ) ); /* q_shift */
190 2382720 : out[k] = P5_fx; /* could overwrite sig */
191 2382720 : move32();
192 :
193 2382720 : D1_fx[( pos + d1 ) & mask] = P2_fx; /* q_shift */
194 2382720 : move32();
195 2382720 : D2_fx[( pos + d2 ) & mask] = P3_fx; /* q_shift */
196 2382720 : move32();
197 2382720 : D3_fx[( pos + d3 ) & mask] = P4_fx; /* q_shift */
198 2382720 : move32();
199 :
200 2382720 : pos = s_and( add( pos, 1 ), mask );
201 : }
202 :
203 96492 : ap->pos = pos;
204 96492 : move16();
205 :
206 96492 : return;
207 : }
|