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 149652 : 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 149652 : 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 149652 : push_wmops( "ivas_sba_prototype_renderer" );
71 :
72 149652 : hSpar = st_ivas->hSpar;
73 149652 : hDecoderConfig = st_ivas->hDecoderConfig;
74 149652 : num_spar_bands = hSpar->hFbMixer->pFb->filterbank_num_bands;
75 149652 : move16();
76 :
77 149652 : num_cldfb_bands = hSpar->hFbMixer->pFb->fb_bin_to_band.num_cldfb_bands;
78 149652 : move16();
79 149652 : numch_in = hSpar->hFbMixer->fb_cfg->num_in_chans;
80 149652 : move16();
81 149652 : numch_out = hSpar->hFbMixer->fb_cfg->num_out_chans;
82 149652 : move16();
83 149652 : slot_idx_start = hSpar->slots_rendered;
84 149652 : move16();
85 :
86 : /* Scaling up the real and imaginary buffers */
87 149652 : Word16 norm_q = 31; // to handle overflow
88 149652 : move16();
89 :
90 448956 : FOR( Word16 i = 0; i < 2; i++ )
91 : {
92 1496520 : FOR( Word16 j = 0; j < CLDFB_SLOTS_PER_SUBFRAME; j++ )
93 : {
94 1197216 : norm_q = s_min( q_cldfb[i][j], norm_q );
95 : }
96 : }
97 149652 : norm_q = sub( sub( 31, norm_q ), 2 ); // to handle overflow
98 : Word16 q_inp[2][CLDFB_SLOTS_PER_SUBFRAME];
99 448956 : FOR( Word16 i = 0; i < 2; i++ )
100 : {
101 1496520 : FOR( Word16 j = 0; j < CLDFB_SLOTS_PER_SUBFRAME; j++ )
102 : {
103 1197216 : q_inp[i][j] = s_min( L_norm_arr( inRe_fx[i][j], num_cldfb_bands ), L_norm_arr( inIm_fx[i][j], num_cldfb_bands ) );
104 1197216 : move16();
105 1197216 : norm_q = s_min( q_inp[i][j], norm_q );
106 : }
107 : }
108 448956 : FOR( Word16 i = 0; i < 2; i++ )
109 : {
110 1496520 : FOR( Word16 j = 0; j < CLDFB_SLOTS_PER_SUBFRAME; j++ )
111 : {
112 1197216 : scale_sig32( inRe_fx[i][j], num_cldfb_bands, sub( norm_q, 2 ) ); // q_cldfb -> q_cldfb + 2 -norm_q
113 1197216 : scale_sig32( inIm_fx[i][j], num_cldfb_bands, sub( norm_q, 2 ) ); // q_cldfb -> q_cldfb + 2 -norm_q
114 1197216 : q_cldfb[i][j] = sub( add( q_cldfb[i][j], norm_q ), 2 );
115 1197216 : move16();
116 : }
117 : }
118 :
119 149652 : IF( EQ_16( st_ivas->nchan_transport, 1 ) )
120 : {
121 64407 : firstInCh = 0;
122 64407 : inChEnd = 1;
123 64407 : firstOutCh = 0;
124 64407 : outChEnd = 1;
125 64407 : move16();
126 64407 : move16();
127 64407 : move16();
128 64407 : move16();
129 : }
130 : ELSE /* 2 TC */
131 : {
132 85245 : firstInCh = 0;
133 85245 : inChEnd = 2;
134 85245 : firstOutCh = 1;
135 85245 : outChEnd = 2;
136 85245 : move16();
137 85245 : move16();
138 85245 : move16();
139 85245 : move16();
140 : }
141 :
142 : /* Apply mixing matrix */
143 742502 : FOR( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ )
144 : {
145 : /* determine SPAR parameters FOR this time slot */
146 592850 : md_idx = hSpar->render_to_md_map[ts + slot_idx_start];
147 592850 : move16();
148 :
149 592850 : ivas_spar_get_parameters_fx( hSpar, hDecoderConfig, md_idx, numch_out, numch_in, num_spar_bands, mixer_mat_fx );
150 :
151 26394250 : 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 25801400 : ivas_fb_bin_to_band_data_t *bin2band = &hSpar->hFbMixer->pFb->fb_bin_to_band;
157 :
158 51602800 : FOR( out_ch = firstOutCh; out_ch < outChEnd; out_ch++ )
159 : {
160 25801400 : out_re_fx[out_ch] = 0;
161 25801400 : move32();
162 25801400 : out_im_fx[out_ch] = 0;
163 25801400 : move32();
164 :
165 66267740 : FOR( in_ch = firstInCh; in_ch < inChEnd; in_ch++ )
166 : {
167 40466340 : 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 6529873 : spar_band = bin2band->p_cldfb_map_to_spar_band[cldfb_band];
170 6529873 : move16();
171 6529873 : cldfb_par_fx = mixer_mat_fx[out_ch][in_ch][spar_band]; // hMdDec->Q_mixer_matrix
172 6529873 : move32();
173 : }
174 : ELSE
175 : {
176 33936467 : cldfb_par_fx = 0;
177 33936467 : move32();
178 196185301 : 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 162248834 : cldfb_par_fx = Madd_32_32( cldfb_par_fx, mixer_mat_fx[out_ch][in_ch][spar_band], L_shl_sat( bin2band->pp_cldfb_weights_per_spar_band_fx[cldfb_band][spar_band], 9 ) ); // hMdDec->Q_mixer_matrix
182 : }
183 : }
184 :
185 40466340 : out_re_fx[out_ch] = Madd_32_32( out_re_fx[out_ch], inRe_fx[in_ch][ts][cldfb_band], cldfb_par_fx ); // hMdDec->Q_mixer_matrix+q_cldfb[i][j] -31
186 40466340 : out_im_fx[out_ch] = Madd_32_32( out_im_fx[out_ch], inIm_fx[in_ch][ts][cldfb_band], cldfb_par_fx ); // hMdDec->Q_mixer_matrix+q_cldfb[i][j] -31
187 40466340 : move32();
188 40466340 : move32();
189 : }
190 : }
191 :
192 : /*update CLDFB data with the parameter-modified data*/
193 51602800 : FOR( out_ch = firstOutCh; out_ch < outChEnd; out_ch++ )
194 : {
195 25801400 : 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 25801400 : 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 25801400 : move32();
198 25801400 : move32();
199 : }
200 : }
201 :
202 : /* Update mixing matrices */
203 592850 : test();
204 592850 : 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 148216 : Word16 md_sf = shr( md_idx, 2 ); // md_idx / JBM_CLDFB_SLOTS_IN_SUBFRAME
208 148216 : if ( NE_16( num_md_sub_frames, MAX_PARAM_SPATIAL_SUBFRAMES ) )
209 : {
210 15732 : md_sf = 0;
211 15732 : move16();
212 : }
213 148216 : hSpar->i_subframe = add( hSpar->i_subframe, 1 );
214 148216 : move16();
215 148216 : hSpar->i_subframe = s_min( hSpar->i_subframe, MAX_PARAM_SPATIAL_SUBFRAMES );
216 148216 : move16();
217 148216 : 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 148216 : 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 148216 : 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 148216 : 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 741080 : FOR( out_ch = 0; out_ch < numch_out; out_ch++ )
223 : {
224 2964320 : FOR( in_ch = 0; in_ch < numch_in; in_ch++ )
225 : {
226 30572928 : FOR( b = 0; b < num_spar_bands; b++ )
227 : {
228 28201472 : 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 28201472 : move32();
230 : }
231 : }
232 : }
233 : }
234 : }
235 :
236 :
237 : /* Create prototypes */
238 149652 : test();
239 149652 : IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) || EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
240 : {
241 742502 : FOR( ts = 0; ts < hSpar->subframe_nbslots[subframe]; ts++ )
242 : {
243 592850 : IF( EQ_16( st_ivas->nchan_transport, 1 ) ) /* Dual mono */
244 : {
245 252861 : Copy32( inRe_fx[0][ts], inRe_fx[1][ts], num_cldfb_bands );
246 252861 : Copy32( inIm_fx[0][ts], inIm_fx[1][ts], num_cldfb_bands );
247 : }
248 339989 : ELSE IF( EQ_16( st_ivas->nchan_transport, 2 ) ) /* Opposing cardioids */
249 : {
250 : Word32 temp_signal_fx;
251 15004929 : FOR( Word16 idx = 0; idx < num_cldfb_bands; idx++ )
252 : {
253 14664940 : Word32 op1 = L_shr( inRe_fx[0][ts][idx], 1 );
254 14664940 : Word32 op2 = L_shr( inRe_fx[1][ts][idx], 1 );
255 14664940 : temp_signal_fx = L_add( op1, op2 ); // q_cldfb[][]-1
256 14664940 : inRe_fx[1][ts][idx] = L_sub( op1, op2 ); // q_cldfb[][]-1
257 14664940 : move32();
258 14664940 : inRe_fx[0][ts][idx] = temp_signal_fx;
259 14664940 : move32();
260 : }
261 :
262 15004929 : FOR( Word16 idx = 0; idx < num_cldfb_bands; idx++ )
263 : {
264 14664940 : Word32 op1 = L_shr( inIm_fx[0][ts][idx], 1 );
265 14664940 : Word32 op2 = L_shr( inIm_fx[1][ts][idx], 1 );
266 14664940 : temp_signal_fx = L_add( op1, op2 ); // q_cldfb[][]-1
267 14664940 : move32();
268 14664940 : inIm_fx[1][ts][idx] = L_sub( op1, op2 ); // q_cldfb[][]-1
269 14664940 : move32();
270 14664940 : inIm_fx[0][ts][idx] = temp_signal_fx;
271 14664940 : move32();
272 : }
273 : }
274 : }
275 : }
276 :
277 149652 : hSpar->subframes_rendered = add( hSpar->subframes_rendered, 1 );
278 149652 : move16();
279 149652 : hSpar->slots_rendered = add( hSpar->slots_rendered, hSpar->subframe_nbslots[subframe] );
280 149652 : move16();
281 149652 : pop_wmops();
282 :
283 149652 : return;
284 : }
|