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