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