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 450150 : 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 450150 : hStereoTCA = hCPE->hStereoTCA;
75 :
76 450150 : output_Fs = hCPE->hCoreCoder[0]->output_Fs;
77 :
78 450150 : if ( hCPE->nchan_out == 1 )
79 : {
80 92418 : if ( hCPE->hStereoDftDmx )
81 : {
82 71424 : if ( hCPE->element_mode == IVAS_CPE_DFT )
83 : {
84 67365 : hCPE->hStereoDftDmx->targetGain = 1.0f;
85 : }
86 :
87 : /* save the target gain for next frame */
88 71424 : hCPE->hStereoDftDmx->prevTargetGain = hCPE->hStereoDftDmx->targetGain;
89 : }
90 :
91 92418 : return;
92 : }
93 357732 : else if ( hCPE->element_mode == IVAS_CPE_MDCT && !hCPE->hStereoMdct->use_itd )
94 : {
95 208398 : return;
96 : }
97 :
98 : /* populate L/R memories into current buffers */
99 149334 : mvr2r( hStereoTCA->memChanL, bufChanL, L_DEC_MEM_LEN_ICA );
100 149334 : mvr2r( hStereoTCA->memChanR, bufChanR, L_DEC_MEM_LEN_ICA );
101 :
102 : /* pointers to the current frame */
103 149334 : ptrChanL = bufChanL + L_DEC_MEM_LEN_ICA;
104 149334 : ptrChanR = bufChanR + L_DEC_MEM_LEN_ICA;
105 :
106 : /* copy interleaved stereo data to two channels, e.g., L, R */
107 149334 : mvr2r( synth[0], ptrChanL, output_frame );
108 149334 : mvr2r( synth[1], ptrChanR, output_frame );
109 :
110 : /* back up the L/R target synth for next frame */
111 149334 : mvr2r( bufChanL + output_frame, hStereoTCA->memChanL, L_DEC_MEM_LEN_ICA );
112 149334 : mvr2r( bufChanR + output_frame, hStereoTCA->memChanR, L_DEC_MEM_LEN_ICA );
113 :
114 : /* TCA parameter de-quantize */
115 149334 : dsFactor = (int16_t) ( output_Fs / 8000 );
116 149334 : tempMax = NS2SA( output_Fs, L_NCSHIFT_NS );
117 149334 : hStereoTCA->corrLagStats = min( hStereoTCA->indx_ica_NCShift * dsFactor, tempMax );
118 :
119 149334 : bothChannelShift = 0;
120 149334 : if ( hCPE->element_mode == IVAS_CPE_DFT || hCPE->element_mode == IVAS_CPE_MDCT )
121 : {
122 142053 : hStereoTCA->corrLagStats = 0;
123 142053 : hStereoTCA->refChanIndx = L_CH_INDX;
124 142053 : hStereoTCA->targetGain = 1.0f;
125 :
126 142053 : if ( hCPE->element_mode == IVAS_CPE_DFT )
127 : {
128 111693 : hStereoTCA->corrLagStats = (int16_t) fabsf( hCPE->hStereoDft->itd[1] );
129 111693 : hStereoTCA->refChanIndx = ( hCPE->hStereoDft->itd[1] >= 0 ) ? ( L_CH_INDX ) : ( R_CH_INDX );
130 : }
131 30360 : else if ( hCPE->element_mode == IVAS_CPE_MDCT )
132 : {
133 : float itd;
134 :
135 30360 : itd = hCPE->hStereoMdct->itd;
136 30360 : hStereoTCA->corrLagStats = (int16_t) fabsf( itd );
137 30360 : hStereoTCA->refChanIndx = ( itd >= 0 ) ? ( L_CH_INDX ) : ( R_CH_INDX );
138 : }
139 :
140 142053 : if ( hStereoTCA->refChanIndx != hStereoTCA->prevRefChanIndx && hStereoTCA->corrLagStats != 0 )
141 : {
142 1170 : bothChannelShift = 1;
143 : }
144 : }
145 :
146 149334 : prevNCShift = (int16_t) abs( hStereoTCA->prevCorrLagStats );
147 149334 : currentNCShift = (int16_t) abs( hStereoTCA->corrLagStats );
148 :
149 149334 : if ( hCPE->element_mode == IVAS_CPE_TD && hCPE->last_element_mode == IVAS_CPE_TD )
150 : {
151 7170 : if ( hStereoTCA->corrLagStats == hStereoTCA->prevCorrLagStats && hStereoTCA->interp_dec_switch_to_zero_diff == 0 )
152 : {
153 3612 : hStereoTCA->interp_dec_switch_to_zero_diff = 1;
154 : }
155 : else
156 : {
157 3558 : hStereoTCA->interp_dec_switch_to_zero_diff = 0;
158 : }
159 :
160 7170 : if ( currentNCShift != 0 )
161 : {
162 12 : currentNCShift = TRUNC( 0.6 * prevNCShift + 0.4 * currentNCShift );
163 : }
164 :
165 7170 : prevNCShift = hStereoTCA->interp_dec_prevNCShift;
166 7170 : hStereoTCA->interp_dec_prevNCShift = currentNCShift;
167 : }
168 : else
169 : {
170 142164 : hStereoTCA->interp_dec_prevNCShift = currentNCShift;
171 142164 : hStereoTCA->interp_dec_switch_to_zero_diff = 0;
172 : }
173 :
174 149334 : ref = ptrChanL;
175 149334 : target = ptrChanR;
176 149334 : target_idx = R_CH_INDX;
177 : /* identify target signal to adjust for shift variations */
178 149334 : if ( ( prevNCShift == 0 && hStereoTCA->refChanIndx == R_CH_INDX ) || ( hStereoTCA->prevRefChanIndx == R_CH_INDX ) )
179 : {
180 45654 : ref = ptrChanR;
181 45654 : target = ptrChanL;
182 45654 : target_idx = L_CH_INDX;
183 : }
184 :
185 149334 : if ( bothChannelShift == 1 )
186 : {
187 1170 : ref = ptrChanL;
188 1170 : target = ptrChanR;
189 1170 : target_idx = R_CH_INDX;
190 1170 : if ( hStereoTCA->refChanIndx == R_CH_INDX )
191 : {
192 927 : ref = ptrChanR;
193 927 : target = ptrChanL;
194 927 : target_idx = L_CH_INDX;
195 : }
196 : }
197 :
198 : /* target signal adjustment for temporal shift variations */
199 149334 : if ( hStereoTCA->prevCorrLagStats != hStereoTCA->corrLagStats || bothChannelShift || ( hStereoTCA->interp_dec_switch_to_zero_diff == 1 && hCPE->element_mode == IVAS_CPE_TD ) )
200 : {
201 10734 : l_shift_adapt = L_SHIFT_ADAPT_16k;
202 10734 : if ( output_Fs > 16000 )
203 : {
204 8481 : l_shift_adapt = L_SHIFT_ADAPT_MAX;
205 : }
206 :
207 10734 : if ( hCPE->element_mode == IVAS_CPE_TD && hCPE->last_element_mode == IVAS_CPE_DFT )
208 : {
209 36 : 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 10734 : if ( abs( currentNCShift - prevNCShift ) <= N_MAX_SHIFT_CHANGE && bothChannelShift == 0 )
218 : {
219 8787 : adjustTargetSignal( target - currentNCShift, currentNCShift, prevNCShift, l_shift_adapt, 0 );
220 : }
221 : else
222 : {
223 1947 : if ( bothChannelShift == 1 )
224 : {
225 1170 : adjustTargetSignal( ref, 0, prevNCShift, l_shift_adapt, 1 );
226 1170 : adjustTargetSignal( target - currentNCShift, currentNCShift, 0, l_shift_adapt, 1 );
227 : }
228 : else
229 : {
230 777 : adjustTargetSignal( target - currentNCShift, currentNCShift, prevNCShift, l_shift_adapt, 1 );
231 : }
232 : }
233 : }
234 :
235 : /* temporal channel adjustment */
236 149334 : mvr2r( target - currentNCShift, synth[target_idx], output_frame );
237 :
238 149334 : mvr2r( ref, synth[!target_idx], output_frame );
239 :
240 : /* Scale the Right channel with the gain */
241 149334 : 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 149334 : hStereoTCA->prevRefChanIndx = hStereoTCA->refChanIndx;
249 :
250 : /* save the corr lag stats for next frame */
251 149334 : hStereoTCA->prevCorrLagStats = hStereoTCA->corrLagStats;
252 :
253 : /* save the target gain for next frame */
254 149334 : hStereoTCA->prevTargetGain = hStereoTCA->targetGain;
255 :
256 149334 : return;
257 : }
258 :
259 : /*-------------------------------------------------------------------*
260 : * stereo_tca_scale_R_channel()
261 : *
262 : * Scale the Right channel with the gain
263 : *-------------------------------------------------------------------*/
264 :
265 153414 : 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 153414 : hStereoTCA = hCPE->hStereoTCA;
277 153414 : output_Fs = hCPE->hCoreCoder[0]->output_Fs;
278 :
279 153414 : if ( hCPE->hCoreCoder[0]->core_brate <= SID_2k40 && hCPE->nchan_out == 2 )
280 : {
281 21747 : return;
282 : }
283 : /* Scale the Right channel with the gain */
284 131667 : l_ica_ovl = NS2SA( output_Fs, STEREO_L_TCA_OVLP_NS );
285 :
286 131667 : if ( hCPE->nchan_out == 1 )
287 : {
288 : /* in mono DMX, the scaling is done before synchro_synthesis() */
289 4080 : flat_old = NS2SA( output_Fs, ACELP_LOOK_NS + IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS );
290 :
291 4080 : if ( hCPE->last_element_mode == IVAS_CPE_TD && hCPE->element_mode == IVAS_CPE_DFT )
292 : {
293 21 : hCPE->hStereoDftDmx->prevTargetGain *= 2.0f;
294 21 : hCPE->hStereoDftDmx->prevTargetGain = min( hCPE->hStereoDftDmx->prevTargetGain, powf( 10, ( ( 1 << STEREO_BITS_TCA_GD ) - 1 ) * STEREO_TCA_GDSTEP + STEREO_TCA_GDMIN ) );
295 21 : hCPE->hStereoDftDmx->targetGain = 1.0f;
296 :
297 21 : flat_old = NS2SA( output_Fs, IVAS_DEC_DELAY_NS );
298 : }
299 : }
300 127587 : else if ( hCPE->last_element_mode == IVAS_CPE_TD && hCPE->element_mode == IVAS_CPE_DFT )
301 : {
302 42 : flat_old = NS2SA( output_Fs, IVAS_DEC_DELAY_NS );
303 : }
304 : else
305 : {
306 127545 : flat_old = NS2SA( output_Fs, ACELP_LOOK_NS + IVAS_DEC_DELAY_NS );
307 : }
308 :
309 131667 : if ( hCPE->nchan_out == 1 )
310 : {
311 4080 : tempF1 = 1.0f / hCPE->hStereoDftDmx->targetGain;
312 4080 : tempF = 1.0f / hCPE->hStereoDftDmx->prevTargetGain;
313 : }
314 : else
315 : {
316 127587 : tempF1 = 1.0f / hStereoTCA->targetGain;
317 127587 : tempF = 1.0f / hStereoTCA->prevTargetGain;
318 : }
319 131667 : winSlope = 1.0f / (float) l_ica_ovl;
320 :
321 50376663 : for ( i = 0; i < flat_old; i++ )
322 : {
323 50244996 : output[i] *= tempF;
324 : }
325 21137907 : for ( j = 0; i < flat_old + l_ica_ovl; i++, j++ )
326 : {
327 21006240 : output[i] = ( 1.0f - j * winSlope ) * tempF * output[i] + ( j * winSlope ) * tempF1 * output[i];
328 : }
329 12905391 : for ( ; i < output_frame; i++ )
330 : {
331 12773724 : output[i] *= tempF1;
332 : }
333 :
334 131667 : return;
335 : }
336 :
337 :
338 : /*-------------------------------------------------------------------*
339 : * stereo_tca_init_dec()
340 : *
341 : * Stereo temporal channel adjustment (TCA) decoder initialization
342 : *-------------------------------------------------------------------*/
343 :
344 1608 : void stereo_tca_init_dec(
345 : STEREO_TCA_DEC_HANDLE hStereoTCA /* i/o: Stereo TCA handle */
346 : )
347 : {
348 1608 : hStereoTCA->refChanIndx = L_CH_INDX;
349 1608 : hStereoTCA->prevRefChanIndx = L_CH_INDX;
350 1608 : hStereoTCA->indx_ica_NCShift = 0;
351 1608 : hStereoTCA->indx_ica_gD = 0;
352 1608 : hStereoTCA->targetGain = 1.0f;
353 1608 : hStereoTCA->prevTargetGain = 1.0f;
354 :
355 1608 : hStereoTCA->corrLagStats = 0;
356 1608 : hStereoTCA->prevCorrLagStats = 0;
357 :
358 1608 : hStereoTCA->interp_dec_prevNCShift = 0;
359 1608 : hStereoTCA->interp_dec_switch_to_zero_diff = 0;
360 :
361 1608 : set_f( hStereoTCA->memChanL, 0.0f, L_DEC_MEM_LEN_ICA );
362 1608 : set_f( hStereoTCA->memChanR, 0.0f, L_DEC_MEM_LEN_ICA );
363 :
364 1608 : return;
365 : }
|