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 "prot_fx.h"
36 : #include "ivas_prot_rend_fx.h"
37 : #include "ivas_stat_dec.h"
38 : #include "ivas_cnst.h"
39 : #include <math.h>
40 : #include "wmc_auto.h"
41 : #include "ivas_prot_fx.h"
42 :
43 : /*-------------------------------------------------------------------*
44 : * ivas_sba_prototype_renderer()
45 : *
46 : * Render prototype audio signals using SBA mixing matrices
47 : *-------------------------------------------------------------------*/
48 149650 : void ivas_sba_prototype_renderer_fx(
49 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */
50 : Word32 inRe_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real Q(q_cldfb[][])*/
51 : Word32 inIm_fx[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, imag Q(q_cldfb[][])*/
52 : Word16 q_cldfb[6][CLDFB_SLOTS_PER_SUBFRAME],
53 : const Word16 subframe /* i : Subframe to render */
54 : )
55 : {
56 : Word32 mixer_mat_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS];
57 : SPAR_DEC_HANDLE hSpar;
58 : DECODER_CONFIG_HANDLE hDecoderConfig;
59 : Word16 num_spar_bands, spar_band;
60 : Word16 b, ts;
61 : Word16 num_cldfb_bands, numch_in, numch_out;
62 : Word16 cldfb_band;
63 : Word16 out_ch, in_ch;
64 : Word16 firstInCh, inChEnd, firstOutCh, outChEnd;
65 : Word16 slot_idx_start, md_idx;
66 : Word16 num_md_sub_frames;
67 :
68 149650 : num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate );
69 :
70 149650 : push_wmops( "ivas_sba_prototype_renderer" );
71 :
72 149650 : hSpar = st_ivas->hSpar;
73 149650 : hDecoderConfig = st_ivas->hDecoderConfig;
74 149650 : num_spar_bands = hSpar->hFbMixer->pFb->filterbank_num_bands;
75 149650 : move16();
76 :
77 149650 : num_cldfb_bands = hSpar->hFbMixer->pFb->fb_bin_to_band.num_cldfb_bands;
78 149650 : move16();
79 149650 : numch_in = hSpar->hFbMixer->fb_cfg->num_in_chans;
80 149650 : move16();
81 149650 : numch_out = hSpar->hFbMixer->fb_cfg->num_out_chans;
82 149650 : move16();
83 149650 : slot_idx_start = hSpar->slots_rendered;
84 149650 : move16();
85 :
86 : /* Scaling up the real and imaginary buffers */
87 149650 : Word16 norm_q = 31; // to handle overflow
88 149650 : move16();
89 :
90 1047550 : FOR( Word16 i = 0; i < 6; i++ )
91 : {
92 4489500 : FOR( Word16 j = 0; j < CLDFB_SLOTS_PER_SUBFRAME; j++ )
93 : {
94 3591600 : norm_q = s_min( q_cldfb[i][j], norm_q );
95 : }
96 : }
97 149650 : norm_q = sub( sub( 31, norm_q ), 2 ); // to handle overflow
98 : Word16 q_inp[6][CLDFB_SLOTS_PER_SUBFRAME];
99 1047550 : FOR( Word16 i = 0; i < 6; i++ )
100 : {
101 4489500 : FOR( Word16 j = 0; j < CLDFB_SLOTS_PER_SUBFRAME; j++ )
102 : {
103 3591600 : q_inp[i][j] = s_min( L_norm_arr( inRe_fx[i][j], CLDFB_NO_CHANNELS_MAX ), L_norm_arr( inIm_fx[i][j], CLDFB_NO_CHANNELS_MAX ) );
104 3591600 : move16();
105 3591600 : norm_q = s_min( q_inp[i][j], norm_q );
106 : }
107 : }
108 1047550 : FOR( Word16 i = 0; i < 6; i++ )
109 : {
110 4489500 : FOR( Word16 j = 0; j < CLDFB_SLOTS_PER_SUBFRAME; j++ )
111 : {
112 3591600 : scale_sig32( inRe_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( norm_q, 2 ) ); // q_cldfb -> q_cldfb + 2 -norm_q
113 3591600 : scale_sig32( inIm_fx[i][j], CLDFB_NO_CHANNELS_MAX, sub( norm_q, 2 ) ); // q_cldfb -> q_cldfb + 2 -norm_q
114 3591600 : q_cldfb[i][j] = sub( add( q_cldfb[i][j], norm_q ), 2 );
115 3591600 : move16();
116 : }
117 : }
118 :
119 149650 : IF( EQ_16( st_ivas->nchan_transport, 1 ) )
120 : {
121 64406 : firstInCh = 0;
122 64406 : inChEnd = 1;
123 64406 : firstOutCh = 0;
124 64406 : outChEnd = 1;
125 64406 : move16();
126 64406 : move16();
127 64406 : move16();
128 64406 : move16();
129 : }
130 : ELSE /* 2 TC */
131 : {
132 85244 : firstInCh = 0;
133 85244 : inChEnd = 2;
134 85244 : firstOutCh = 1;
135 85244 : outChEnd = 2;
136 85244 : move16();
137 85244 : move16();
138 85244 : move16();
139 85244 : move16();
140 : }
141 :
142 : /* Apply mixing matrix */
143 742498 : FOR( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ )
144 : {
145 : /* determine SPAR parameters FOR this time slot */
146 592848 : md_idx = hSpar->render_to_md_map[ts + slot_idx_start];
147 592848 : move16();
148 :
149 592848 : ivas_spar_get_parameters_fx( hSpar, hDecoderConfig, md_idx, numch_out, numch_in, num_spar_bands, mixer_mat_fx );
150 :
151 26394128 : FOR( cldfb_band = 0; cldfb_band < num_cldfb_bands; cldfb_band++ )
152 : {
153 : Word32 out_re_fx[IVAS_SPAR_MAX_CH];
154 : Word32 out_im_fx[IVAS_SPAR_MAX_CH];
155 : Word32 cldfb_par_fx;
156 25801280 : ivas_fb_bin_to_band_data_t *bin2band = &hSpar->hFbMixer->pFb->fb_bin_to_band;
157 :
158 51602560 : FOR( out_ch = firstOutCh; out_ch < outChEnd; out_ch++ )
159 : {
160 25801280 : out_re_fx[out_ch] = 0;
161 25801280 : move32();
162 25801280 : out_im_fx[out_ch] = 0;
163 25801280 : move32();
164 :
165 66267440 : FOR( in_ch = firstInCh; in_ch < inChEnd; in_ch++ )
166 : {
167 40466160 : IF( LT_16( cldfb_band, CLDFB_PAR_WEIGHT_START_BAND ) ) /* tuning parameter, depends on how much SPAR Filters overlap FOR the CLDFB bands */
168 : {
169 6529852 : spar_band = bin2band->p_cldfb_map_to_spar_band[cldfb_band];
170 6529852 : move16();
171 6529852 : cldfb_par_fx = mixer_mat_fx[out_ch][in_ch][spar_band]; // hMdDec->Q_mixer_matrix
172 6529852 : move32();
173 : }
174 : ELSE
175 : {
176 33936308 : cldfb_par_fx = 0;
177 33936308 : move32();
178 196184524 : FOR( spar_band = bin2band->p_spar_start_bands[cldfb_band]; spar_band < num_spar_bands; spar_band++ )
179 : {
180 : /* accumulate contributions from all SPAR bands */
181 162248216 : cldfb_par_fx = L_add( cldfb_par_fx, Mpy_32_32( mixer_mat_fx[out_ch][in_ch][spar_band], bin2band->pp_cldfb_weights_per_spar_band_fx[cldfb_band][spar_band] ) ); // hMdDec->Q_mixer_matrix
182 : }
183 : }
184 :
185 40466160 : out_re_fx[out_ch] = L_add( out_re_fx[out_ch], Mpy_32_32( inRe_fx[in_ch][ts][cldfb_band], cldfb_par_fx ) ); // hMdDec->Q_mixer_matrix+q_cldfb[i][j] -31
186 40466160 : out_im_fx[out_ch] = L_add( out_im_fx[out_ch], Mpy_32_32( inIm_fx[in_ch][ts][cldfb_band], cldfb_par_fx ) ); // hMdDec->Q_mixer_matrix+q_cldfb[i][j] -31
187 40466160 : move32();
188 40466160 : move32();
189 : }
190 : }
191 :
192 : /*update CLDFB data with the parameter-modified data*/
193 51602560 : FOR( out_ch = firstOutCh; out_ch < outChEnd; out_ch++ )
194 : {
195 25801280 : inRe_fx[out_ch][ts][cldfb_band] = L_shl( out_re_fx[out_ch], 1 ); // hMdDec->Q_mixer_matrix+q_cldfb[i][j] -31 +1; + q1 //to keep constat q to entire buffer
196 25801280 : inIm_fx[out_ch][ts][cldfb_band] = L_shl( out_im_fx[out_ch], 1 ); // hMdDec->Q_mixer_matrix+q_cldfb[i][j] -31 +1; + q1 //to keep constat q to entire buffer
197 25801280 : move32();
198 25801280 : move32();
199 : }
200 : }
201 :
202 : /* Update mixing matrices */
203 592848 : test();
204 592848 : IF( EQ_16( add( add( slot_idx_start, ts ), 1 ), hSpar->num_slots ) || NE_16( shr( md_idx, 2 ), shr( hSpar->render_to_md_map[add( add( ts, slot_idx_start ), 1 )], 2 ) ) ) // shr is used in place of division by JBM_CLDFB_SLOTS_IN_SUBFRAME, ( ( md_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME ) != ( hSpar->render_to_md_map[ts + slot_idx_start + 1] / JBM_CLDFB_SLOTS_IN_SUBFRAME ) )
205 : {
206 : /* we have crossed an unadapted parameter sf border, update previous mixing matrices */
207 148214 : Word16 md_sf = shr( md_idx, 2 ); // md_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME
208 148214 : if ( NE_16( num_md_sub_frames, MAX_PARAM_SPATIAL_SUBFRAMES ) )
209 : {
210 15731 : md_sf = 0;
211 15731 : move16();
212 : }
213 148214 : hSpar->i_subframe = add( hSpar->i_subframe, 1 );
214 148214 : move16();
215 148214 : hSpar->i_subframe = s_min( hSpar->i_subframe, MAX_PARAM_SPATIAL_SUBFRAMES );
216 148214 : move16();
217 148214 : Copy32( hSpar->hMdDec->mixer_mat_prev_fx[1][0][0], hSpar->hMdDec->mixer_mat_prev_fx[0][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); // Q_mixer_mat
218 148214 : Copy32( hSpar->hMdDec->mixer_mat_prev_fx[2][0][0], hSpar->hMdDec->mixer_mat_prev_fx[1][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); // Q_mixer_mat
219 148214 : Copy32( hSpar->hMdDec->mixer_mat_prev_fx[3][0][0], hSpar->hMdDec->mixer_mat_prev_fx[2][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); // Q_mixer_mat
220 148214 : Copy32( hSpar->hMdDec->mixer_mat_prev_fx[4][0][0], hSpar->hMdDec->mixer_mat_prev_fx[3][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); // Q_mixer_mat
221 :
222 741070 : FOR( out_ch = 0; out_ch < numch_out; out_ch++ )
223 : {
224 2964280 : FOR( in_ch = 0; in_ch < numch_in; in_ch++ )
225 : {
226 30572512 : FOR( b = 0; b < num_spar_bands; b++ )
227 : {
228 28201088 : hSpar->hMdDec->mixer_mat_prev_fx[4][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat_fx[out_ch][in_ch][b + ( md_sf * IVAS_MAX_NUM_BANDS )];
229 28201088 : move32();
230 : }
231 : }
232 : }
233 : }
234 : }
235 :
236 :
237 : /* Create prototypes */
238 149650 : test();
239 149650 : IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
240 : {
241 742498 : FOR( ts = 0; ts < hSpar->subframe_nbslots[subframe]; ts++ )
242 : {
243 592848 : IF( EQ_16( st_ivas->nchan_transport, 1 ) ) /* Dual mono */
244 : {
245 252860 : Copy32( inRe_fx[0][ts], inRe_fx[1][ts], CLDFB_NO_CHANNELS_MAX );
246 252860 : Copy32( inIm_fx[0][ts], inIm_fx[1][ts], CLDFB_NO_CHANNELS_MAX );
247 : }
248 339988 : ELSE IF( EQ_16( st_ivas->nchan_transport, 2 ) ) /* Opposing cardioids */
249 : {
250 : Word32 temp_signal_fx[CLDFB_NO_CHANNELS_MAX];
251 20739268 : FOR( Word16 idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ )
252 : {
253 20399280 : temp_signal_fx[idx] = L_add( L_shr( inRe_fx[0][ts][idx], 1 ), L_shr( inRe_fx[1][ts][idx], 1 ) ); // q_cldfb[][]-1
254 20399280 : move32();
255 20399280 : inRe_fx[1][ts][idx] = L_sub( L_shr( inRe_fx[0][ts][idx], 1 ), L_shr( inRe_fx[1][ts][idx], 1 ) ); // q_cldfb[][]-1
256 20399280 : move32();
257 20399280 : inRe_fx[0][ts][idx] = temp_signal_fx[idx];
258 20399280 : move32();
259 : }
260 :
261 20739268 : FOR( Word16 idx = 0; idx < CLDFB_NO_CHANNELS_MAX; idx++ )
262 : {
263 20399280 : temp_signal_fx[idx] = L_add( L_shr( inIm_fx[0][ts][idx], 1 ), L_shr( inIm_fx[1][ts][idx], 1 ) ); // q_cldfb[][]-1
264 20399280 : move32();
265 20399280 : inIm_fx[1][ts][idx] = L_sub( L_shr( inIm_fx[0][ts][idx], 1 ), L_shr( inIm_fx[1][ts][idx], 1 ) ); // q_cldfb[][]-1
266 20399280 : move32();
267 20399280 : inIm_fx[0][ts][idx] = temp_signal_fx[idx];
268 20399280 : move32();
269 : }
270 : }
271 : }
272 : }
273 :
274 149650 : hSpar->subframes_rendered = add( hSpar->subframes_rendered, 1 );
275 149650 : move16();
276 149650 : hSpar->slots_rendered = add( hSpar->slots_rendered, hSpar->subframe_nbslots[subframe] );
277 149650 : move16();
278 149650 : pop_wmops();
279 :
280 149650 : return;
281 : }
|