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 <assert.h>
34 : #include <stdint.h>
35 : #include "options.h"
36 : #include <math.h>
37 : #include "cnst.h"
38 : #include "ivas_cnst.h"
39 : #include "prot.h"
40 : #include "ivas_prot.h"
41 : #ifdef DEBUGGING
42 : #include "debug.h"
43 : #endif
44 : #include "wmc_auto.h"
45 : #include "rom_com.h"
46 : #include "ivas_rom_com.h"
47 :
48 :
49 : /*---------------------------------------------------------------
50 : * stereo_tca_dec()
51 : *
52 : * Stereo temporal channel adjustment/allocation processing module;
53 : * upnmix, convert L/R to M/S.
54 : * ---------------------------------------------------------------*/
55 :
56 4279775 : void stereo_tca_dec(
57 : CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */
58 : float *synth[CPE_CHANNELS], /* i/o: output synth */
59 : const int16_t output_frame /* i : length of a frame per channel */
60 : )
61 : {
62 : /* Buffers, input Left and right channels @ input_Fs*/
63 : float bufChanL[L_DEC_MEM_LEN_ICA + L_FRAME48k];
64 : float bufChanR[L_DEC_MEM_LEN_ICA + L_FRAME48k];
65 : float *ptrChanL, *ptrChanR;
66 : float *target;
67 : int16_t target_idx, prevNCShift, currentNCShift, l_shift_adapt;
68 : int16_t dsFactor, tempMax;
69 : float *ref;
70 : int16_t bothChannelShift;
71 : int32_t output_Fs;
72 : STEREO_TCA_DEC_HANDLE hStereoTCA;
73 :
74 4279775 : hStereoTCA = hCPE->hStereoTCA;
75 :
76 4279775 : output_Fs = hCPE->hCoreCoder[0]->output_Fs;
77 :
78 4279775 : if ( hCPE->nchan_out == 1 )
79 : {
80 629824 : if ( hCPE->hStereoDftDmx )
81 : {
82 512489 : if ( hCPE->element_mode == IVAS_CPE_DFT )
83 : {
84 504968 : hCPE->hStereoDftDmx->targetGain = 1.0f;
85 : }
86 :
87 : /* save the target gain for next frame */
88 512489 : hCPE->hStereoDftDmx->prevTargetGain = hCPE->hStereoDftDmx->targetGain;
89 : }
90 :
91 629824 : return;
92 : }
93 3649951 : else if ( hCPE->element_mode == IVAS_CPE_MDCT && !hCPE->hStereoMdct->use_itd )
94 : {
95 2795723 : return;
96 : }
97 :
98 : /* populate L/R memories into current buffers */
99 854228 : mvr2r( hStereoTCA->memChanL, bufChanL, L_DEC_MEM_LEN_ICA );
100 854228 : mvr2r( hStereoTCA->memChanR, bufChanR, L_DEC_MEM_LEN_ICA );
101 :
102 : /* pointers to the current frame */
103 854228 : ptrChanL = bufChanL + L_DEC_MEM_LEN_ICA;
104 854228 : ptrChanR = bufChanR + L_DEC_MEM_LEN_ICA;
105 :
106 : /* copy interleaved stereo data to two channels, e.g., L, R */
107 854228 : mvr2r( synth[0], ptrChanL, output_frame );
108 854228 : mvr2r( synth[1], ptrChanR, output_frame );
109 :
110 : /* back up the L/R target synth for next frame */
111 854228 : mvr2r( bufChanL + output_frame, hStereoTCA->memChanL, L_DEC_MEM_LEN_ICA );
112 854228 : mvr2r( bufChanR + output_frame, hStereoTCA->memChanR, L_DEC_MEM_LEN_ICA );
113 :
114 : /* TCA parameter de-quantize */
115 854228 : dsFactor = (int16_t) ( output_Fs / 8000 );
116 854228 : tempMax = NS2SA( output_Fs, L_NCSHIFT_NS );
117 854228 : hStereoTCA->corrLagStats = min( hStereoTCA->indx_ica_NCShift * dsFactor, tempMax );
118 :
119 854228 : bothChannelShift = 0;
120 854228 : if ( hCPE->element_mode == IVAS_CPE_DFT || hCPE->element_mode == IVAS_CPE_MDCT )
121 : {
122 822615 : hStereoTCA->corrLagStats = 0;
123 822615 : hStereoTCA->refChanIndx = L_CH_INDX;
124 822615 : hStereoTCA->targetGain = 1.0f;
125 :
126 822615 : if ( hCPE->element_mode == IVAS_CPE_DFT )
127 : {
128 683545 : hStereoTCA->corrLagStats = (int16_t) fabsf( hCPE->hStereoDft->itd[1] );
129 683545 : hStereoTCA->refChanIndx = ( hCPE->hStereoDft->itd[1] >= 0 ) ? ( L_CH_INDX ) : ( R_CH_INDX );
130 : }
131 139070 : else if ( hCPE->element_mode == IVAS_CPE_MDCT )
132 : {
133 : float itd;
134 :
135 139070 : itd = hCPE->hStereoMdct->itd;
136 139070 : hStereoTCA->corrLagStats = (int16_t) fabsf( itd );
137 139070 : hStereoTCA->refChanIndx = ( itd >= 0 ) ? ( L_CH_INDX ) : ( R_CH_INDX );
138 : }
139 :
140 822615 : if ( hStereoTCA->refChanIndx != hStereoTCA->prevRefChanIndx && hStereoTCA->corrLagStats != 0 )
141 : {
142 6031 : bothChannelShift = 1;
143 : }
144 : }
145 :
146 854228 : prevNCShift = (int16_t) abs( hStereoTCA->prevCorrLagStats );
147 854228 : currentNCShift = (int16_t) abs( hStereoTCA->corrLagStats );
148 :
149 854228 : if ( hCPE->element_mode == IVAS_CPE_TD && hCPE->last_element_mode == IVAS_CPE_TD )
150 : {
151 30884 : if ( hStereoTCA->corrLagStats == hStereoTCA->prevCorrLagStats && hStereoTCA->interp_dec_switch_to_zero_diff == 0 )
152 : {
153 15562 : hStereoTCA->interp_dec_switch_to_zero_diff = 1;
154 : }
155 : else
156 : {
157 15322 : hStereoTCA->interp_dec_switch_to_zero_diff = 0;
158 : }
159 :
160 30884 : if ( currentNCShift != 0 )
161 : {
162 1103 : currentNCShift = TRUNC( 0.6 * prevNCShift + 0.4 * currentNCShift );
163 : }
164 :
165 30884 : prevNCShift = hStereoTCA->interp_dec_prevNCShift;
166 30884 : hStereoTCA->interp_dec_prevNCShift = currentNCShift;
167 : }
168 : else
169 : {
170 823344 : hStereoTCA->interp_dec_prevNCShift = currentNCShift;
171 823344 : hStereoTCA->interp_dec_switch_to_zero_diff = 0;
172 : }
173 :
174 854228 : ref = ptrChanL;
175 854228 : target = ptrChanR;
176 854228 : target_idx = R_CH_INDX;
177 : /* identify target signal to adjust for shift variations */
178 854228 : if ( ( prevNCShift == 0 && hStereoTCA->refChanIndx == R_CH_INDX ) || ( hStereoTCA->prevRefChanIndx == R_CH_INDX ) )
179 : {
180 172147 : ref = ptrChanR;
181 172147 : target = ptrChanL;
182 172147 : target_idx = L_CH_INDX;
183 : }
184 :
185 854228 : if ( bothChannelShift == 1 )
186 : {
187 6031 : ref = ptrChanL;
188 6031 : target = ptrChanR;
189 6031 : target_idx = R_CH_INDX;
190 6031 : if ( hStereoTCA->refChanIndx == R_CH_INDX )
191 : {
192 4465 : ref = ptrChanR;
193 4465 : target = ptrChanL;
194 4465 : target_idx = L_CH_INDX;
195 : }
196 : }
197 :
198 : /* target signal adjustment for temporal shift variations */
199 854228 : if ( hStereoTCA->prevCorrLagStats != hStereoTCA->corrLagStats || bothChannelShift || ( hStereoTCA->interp_dec_switch_to_zero_diff == 1 && hCPE->element_mode == IVAS_CPE_TD ) )
200 : {
201 49680 : l_shift_adapt = L_SHIFT_ADAPT_16k;
202 49680 : if ( output_Fs > 16000 )
203 : {
204 40118 : l_shift_adapt = L_SHIFT_ADAPT_MAX;
205 : }
206 :
207 49680 : if ( hCPE->element_mode == IVAS_CPE_TD && hCPE->last_element_mode == IVAS_CPE_DFT )
208 : {
209 273 : l_shift_adapt = l_shift_adapt >> 1;
210 : }
211 :
212 : #ifdef DEBUGGING
213 : /* Max sample looked in INTERP1 should lie within the bounds of output_frame and memory populated */
214 : assert( ( ( min( N_MAX_SHIFT_CHANGE, N_MAX_SHIFT_CHANGE * output_Fs / 32000.0f ) + 1 ) + SINC_ORDER1 / INTERP_FACTOR1 ) + l_shift_adapt - currentNCShift < output_frame );
215 : assert( ( ( min( N_MAX_SHIFT_CHANGE, N_MAX_SHIFT_CHANGE * output_Fs / 32000.0f ) + 1 ) + SINC_ORDER1 / INTERP_FACTOR1 + currentNCShift ) <= L_DEC_MEM_LEN_ICA );
216 : #endif
217 49680 : if ( abs( currentNCShift - prevNCShift ) <= N_MAX_SHIFT_CHANGE && bothChannelShift == 0 )
218 : {
219 41828 : adjustTargetSignal( target - currentNCShift, currentNCShift, prevNCShift, l_shift_adapt, 0 );
220 : }
221 : else
222 : {
223 7852 : if ( bothChannelShift == 1 )
224 : {
225 6031 : adjustTargetSignal( ref, 0, prevNCShift, l_shift_adapt, 1 );
226 6031 : adjustTargetSignal( target - currentNCShift, currentNCShift, 0, l_shift_adapt, 1 );
227 : }
228 : else
229 : {
230 1821 : adjustTargetSignal( target - currentNCShift, currentNCShift, prevNCShift, l_shift_adapt, 1 );
231 : }
232 : }
233 : }
234 :
235 : /* temporal channel adjustment */
236 854228 : mvr2r( target - currentNCShift, synth[target_idx], output_frame );
237 :
238 854228 : mvr2r( ref, synth[!target_idx], output_frame );
239 :
240 : /* Scale the Right channel with the gain */
241 854228 : stereo_tca_scale_R_channel( hCPE, synth[1], output_frame );
242 :
243 : /*-----------------------------------------------------------------*
244 : * updates and memory backups
245 : *-----------------------------------------------------------------*/
246 :
247 : /* save the reference channel index for next frame */
248 854228 : hStereoTCA->prevRefChanIndx = hStereoTCA->refChanIndx;
249 :
250 : /* save the corr lag stats for next frame */
251 854228 : hStereoTCA->prevCorrLagStats = hStereoTCA->corrLagStats;
252 :
253 : /* save the target gain for next frame */
254 854228 : hStereoTCA->prevTargetGain = hStereoTCA->targetGain;
255 :
256 854228 : return;
257 : }
258 :
259 : /*-------------------------------------------------------------------*
260 : * stereo_tca_scale_R_channel()
261 : *
262 : * Scale the Right channel with the gain
263 : *-------------------------------------------------------------------*/
264 :
265 861850 : void stereo_tca_scale_R_channel(
266 : CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */
267 : float *output, /* i/o: output synthesis, R channel */
268 : const int16_t output_frame /* i : frame length */
269 : )
270 : {
271 : STEREO_TCA_DEC_HANDLE hStereoTCA;
272 : int16_t i, j, l_ica_ovl, flat_old;
273 : float tempF, tempF1, winSlope;
274 : int32_t output_Fs;
275 :
276 861850 : hStereoTCA = hCPE->hStereoTCA;
277 861850 : output_Fs = hCPE->hCoreCoder[0]->output_Fs;
278 :
279 861850 : if ( hCPE->hCoreCoder[0]->core_brate <= SID_2k40 && hCPE->nchan_out == 2 )
280 : {
281 42167 : return;
282 : }
283 : /* Scale the Right channel with the gain */
284 819683 : l_ica_ovl = NS2SA( output_Fs, STEREO_L_TCA_OVLP_NS );
285 :
286 819683 : if ( hCPE->nchan_out == 1 )
287 : {
288 : /* in mono DMX, the scaling is done before synchro_synthesis() */
289 7622 : flat_old = NS2SA( output_Fs, ACELP_LOOK_NS + IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS );
290 :
291 7622 : if ( hCPE->last_element_mode == IVAS_CPE_TD && hCPE->element_mode == IVAS_CPE_DFT )
292 : {
293 101 : hCPE->hStereoDftDmx->prevTargetGain *= 2.0f;
294 101 : hCPE->hStereoDftDmx->prevTargetGain = min( hCPE->hStereoDftDmx->prevTargetGain, powf( 10, ( ( 1 << STEREO_BITS_TCA_GD ) - 1 ) * STEREO_TCA_GDSTEP + STEREO_TCA_GDMIN ) );
295 101 : hCPE->hStereoDftDmx->targetGain = 1.0f;
296 :
297 101 : flat_old = NS2SA( output_Fs, IVAS_DEC_DELAY_NS );
298 : }
299 : }
300 812061 : else if ( hCPE->last_element_mode == IVAS_CPE_TD && hCPE->element_mode == IVAS_CPE_DFT )
301 : {
302 388 : flat_old = NS2SA( output_Fs, IVAS_DEC_DELAY_NS );
303 : }
304 : else
305 : {
306 811673 : flat_old = NS2SA( output_Fs, ACELP_LOOK_NS + IVAS_DEC_DELAY_NS );
307 : }
308 :
309 819683 : if ( hCPE->nchan_out == 1 )
310 : {
311 7622 : tempF1 = 1.0f / hCPE->hStereoDftDmx->targetGain;
312 7622 : tempF = 1.0f / hCPE->hStereoDftDmx->prevTargetGain;
313 : }
314 : else
315 : {
316 812061 : tempF1 = 1.0f / hStereoTCA->targetGain;
317 812061 : tempF = 1.0f / hStereoTCA->prevTargetGain;
318 : }
319 819683 : winSlope = 1.0f / (float) l_ica_ovl;
320 :
321 328309555 : for ( i = 0; i < flat_old; i++ )
322 : {
323 327489872 : output[i] *= tempF;
324 : }
325 137458563 : for ( j = 0; i < flat_old + l_ica_ovl; i++, j++ )
326 : {
327 136638880 : output[i] = ( 1.0f - j * winSlope ) * tempF * output[i] + ( j * winSlope ) * tempF1 * output[i];
328 : }
329 83246451 : for ( ; i < output_frame; i++ )
330 : {
331 82426768 : output[i] *= tempF1;
332 : }
333 :
334 819683 : return;
335 : }
336 :
337 :
338 : /*-------------------------------------------------------------------*
339 : * stereo_tca_init_dec()
340 : *
341 : * Stereo temporal channel adjustment (TCA) decoder initialization
342 : *-------------------------------------------------------------------*/
343 :
344 16451 : void stereo_tca_init_dec(
345 : STEREO_TCA_DEC_HANDLE hStereoTCA /* i/o: Stereo TCA handle */
346 : )
347 : {
348 16451 : hStereoTCA->refChanIndx = L_CH_INDX;
349 16451 : hStereoTCA->prevRefChanIndx = L_CH_INDX;
350 16451 : hStereoTCA->indx_ica_NCShift = 0;
351 16451 : hStereoTCA->indx_ica_gD = 0;
352 16451 : hStereoTCA->targetGain = 1.0f;
353 16451 : hStereoTCA->prevTargetGain = 1.0f;
354 :
355 16451 : hStereoTCA->corrLagStats = 0;
356 16451 : hStereoTCA->prevCorrLagStats = 0;
357 :
358 16451 : hStereoTCA->interp_dec_prevNCShift = 0;
359 16451 : hStereoTCA->interp_dec_switch_to_zero_diff = 0;
360 :
361 16451 : set_f( hStereoTCA->memChanL, 0.0f, L_DEC_MEM_LEN_ICA );
362 16451 : set_f( hStereoTCA->memChanR, 0.0f, L_DEC_MEM_LEN_ICA );
363 :
364 16451 : return;
365 : }
|