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 "prot.h"
39 : #include "ivas_prot.h"
40 : #include "ivas_cnst.h"
41 : #include "ivas_rom_com.h"
42 : #include "ivas_rom_dec.h"
43 : #include "rom_com.h"
44 : #ifdef DEBUGGING
45 : #include "debug.h"
46 : #endif
47 : #include "wmc_auto.h"
48 :
49 :
50 : /*-------------------------------------------------------------------------
51 : * stereo_dft_dmx_out_reset()
52 : *
53 : * Reset DFT stereo mono output memories
54 : *------------------------------------------------------------------------*/
55 :
56 1824 : void stereo_dft_dmx_out_reset(
57 : STEREO_DFT_DMX_DATA_HANDLE hStereoDftDmx /* i/o: DFT stereo DMX decoder */
58 : )
59 : {
60 1824 : hStereoDftDmx->targetGain = 1.0f;
61 1824 : hStereoDftDmx->prevTargetGain = 1.0f;
62 :
63 1824 : set_zero( hStereoDftDmx->memOutHB, NS2SA( 48000, STEREO_DFT32MS_OVL_NS ) );
64 1824 : set_zero( hStereoDftDmx->memTransitionHB, NS2SA( 48000, STEREO_DFT32MS_OVL_NS ) );
65 :
66 1824 : return;
67 : }
68 :
69 :
70 : /*-------------------------------------------------------------------------
71 : * stereo_dft_unify_dmx()
72 : *
73 : * create a uniform dmx in case of residual coding by converting from passive
74 : * to active dmx in residual coding region
75 : *-------------------------------------------------------------------------*/
76 :
77 16026 : void stereo_dft_unify_dmx(
78 : STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder stereo handle */
79 : Decoder_State *st0, /* i/o: decoder state structure */
80 : float DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* i/o: DFT buffers */
81 : float *input_mem, /* i/o: mem of buffer DFT analysis */
82 : const int16_t prev_sid_nodata /* i : Previous SID/No data indicator */
83 : )
84 : {
85 : int16_t i, k, b, N_div;
86 : float DFT_L[STEREO_DFT32MS_N_MAX];
87 : float DFT_R[STEREO_DFT32MS_N_MAX];
88 : float *pDFT_DMX;
89 : float *pDFT_RES;
90 : float g, tmp;
91 : float *pSideGain;
92 : int16_t k_offset;
93 :
94 : /* Variables for stereo residual PLC */
95 : float DFT_PRED_RES[STEREO_DFT32MS_N_32k];
96 : float samp_ratio;
97 : int16_t prev_bfi;
98 : float dmx_nrg;
99 : float *pPredGain;
100 : int16_t stop;
101 : int16_t output_frame;
102 : int16_t plocs[STEREO_DFT_RES_N_PEAKS_MAX];
103 : int16_t num_plocs;
104 : float plocsi[STEREO_DFT_RES_N_PEAKS_MAX];
105 :
106 16026 : output_frame = (int16_t) ( st0->output_Fs / FRAMES_PER_SEC );
107 16026 : samp_ratio = (float) st0->sr_core / (float) st0->output_Fs;
108 16026 : prev_bfi = st0->prev_old_bfi;
109 :
110 : /* Initialization */
111 16026 : k_offset = 1;
112 16026 : N_div = STEREO_DFT_NBDIV;
113 :
114 16026 : dmx_nrg = 0.0f;
115 : /* make sure number of bands corresponds to output bwidth in case it is lower than parameter bwidth */
116 16026 : if ( output_frame < inner_frame_tbl[st0->bwidth] )
117 : {
118 3693 : hStereoDft->nbands = stereo_dft_band_config( hStereoDft->band_limits, hStereoDft->band_res[k_offset], hStereoDft->NFFT, DEC );
119 : }
120 16026 : if ( prev_bfi )
121 : {
122 783 : dmx_nrg = stereo_dft_dmx_swb_nrg( DFT[0], DFT[0] + STEREO_DFT32MS_N_MAX, min( hStereoDft->NFFT, STEREO_DFT32MS_N_32k ) );
123 : }
124 :
125 : /* Analyze nature of current frame */
126 14940 : hStereoDft->trans = ( ( ( st0->clas_dec == ONSET ) || ( st0->clas_dec == SIN_ONSET ) || ( st0->clas_dec == UNVOICED_CLAS ) || ( st0->clas_dec == UNVOICED_TRANSITION ) ) || ( st0->stab_fac <= 0.25f ) ) ||
127 30966 : ( st0->core == TCX_20_CORE && ( ( st0->hTcxCfg->tcx_last_overlap_mode == MIN_OVERLAP ) || ( st0->hTcxCfg->tcx_last_overlap_mode == HALF_OVERLAP ) ) ) || ( st0->core == TCX_10_CORE );
128 :
129 : /* Smoothing for the current frame */
130 16026 : stereo_dft_dec_smooth_parameters( hStereoDft, prev_sid_nodata, st0->hFdCngDec->hFdCngCom->active_frame_counter, st0->element_brate );
131 :
132 48078 : for ( k = 0; k < N_div; k++ )
133 : {
134 32052 : pDFT_DMX = DFT[0] + k * STEREO_DFT32MS_N_MAX;
135 32052 : pDFT_RES = DFT[1] + k * STEREO_DFT32MS_N_MAX;
136 :
137 32052 : assert( hStereoDft->hConfig->dmx_active );
138 : /*Apply Stereo*/
139 32052 : g = 1.f;
140 :
141 : /* since delay is just 3.125ms, the parameters received are used for the second window */
142 32052 : pSideGain = hStereoDft->side_gain + ( k + k_offset ) * STEREO_DFT_BAND_MAX;
143 :
144 :
145 : /* Stereo residual PLC */
146 32052 : if ( hStereoDft->res_cod_band_max > 0 )
147 : {
148 32052 : if ( !st0->bfi )
149 : {
150 30462 : if ( k == 1 )
151 : {
152 15231 : mvr2r( pDFT_RES, hStereoDft->res_mem, 2 * hStereoDft->band_limits[hStereoDft->res_cod_band_max] );
153 15231 : hStereoDft->time_offs = 0;
154 : }
155 : }
156 : else
157 : {
158 1590 : hStereoDft->nbands = hStereoDft->res_cod_band_max; /* Limit nbands since residual PLC only needs the low frequency range of the stereo filling */
159 1590 : pPredGain = hStereoDft->res_pred_gain + ( k + k_offset ) * STEREO_DFT_BAND_MAX;
160 1590 : hStereoDft->past_DMX_pos = ( hStereoDft->past_DMX_pos + STEREO_DFT_PAST_MAX - 1 ) % STEREO_DFT_PAST_MAX;
161 1590 : stereo_dft_generate_res_pred( hStereoDft, samp_ratio, pDFT_DMX, DFT_PRED_RES, pPredGain, k, DFT[1] + k * STEREO_DFT32MS_N_MAX, &stop, st0->bfi );
162 1590 : stereo_dft_res_ecu( hStereoDft, pDFT_RES, DFT_PRED_RES, k, output_frame, prev_bfi, dmx_nrg, &num_plocs, plocs, plocsi, input_mem );
163 : }
164 : }
165 :
166 :
167 : /* Apply active DMX */
168 32052 : DFT_L[0] = pDFT_DMX[0];
169 32052 : DFT_R[0] = pDFT_DMX[0];
170 :
171 : /* upmix residual part */
172 192312 : for ( b = 0; b < hStereoDft->res_cod_band_max; b++ )
173 : {
174 160260 : g = pSideGain[b];
175 :
176 : #ifdef DEBUG_MODE_DFT
177 : dbgwrite( &g, sizeof( float ), 1, 1, "./res/stereo_dft_dec_g.pcm" );
178 : #endif
179 :
180 801300 : for ( i = hStereoDft->band_limits[b]; i < hStereoDft->band_limits[b + 1]; i++ )
181 : {
182 641040 : tmp = g * pDFT_DMX[2 * i] + pDFT_RES[2 * i];
183 :
184 641040 : DFT_L[2 * i] = pDFT_DMX[2 * i] + tmp;
185 641040 : DFT_R[2 * i] = pDFT_DMX[2 * i] - tmp;
186 :
187 641040 : tmp = g * pDFT_DMX[2 * i + 1] + pDFT_RES[2 * i + 1];
188 :
189 641040 : DFT_L[2 * i + 1] = pDFT_DMX[2 * i + 1] + tmp;
190 641040 : DFT_R[2 * i + 1] = pDFT_DMX[2 * i + 1] - tmp;
191 : }
192 : }
193 :
194 : /* downmix residual part with active downmix */
195 192312 : for ( b = 0; b < hStereoDft->res_cod_band_max; b++ )
196 : {
197 : int16_t j;
198 160260 : float sum_nrg_L = EPSILON, sum_nrg_R = EPSILON, dot_prod_real = EPSILON, dot_prod_img = EPSILON;
199 : float sum_nrg_Mid, sum_abs, dot_prod_abs;
200 : float wR, wL;
201 :
202 801300 : for ( j = hStereoDft->band_limits[b]; j < hStereoDft->band_limits[b + 1]; j++ )
203 : {
204 641040 : sum_nrg_L += DFT_L[2 * j] * DFT_L[2 * j] + DFT_L[2 * j + 1] * DFT_L[2 * j + 1];
205 641040 : sum_nrg_R += DFT_R[2 * j] * DFT_R[2 * j] + DFT_R[2 * j + 1] * DFT_R[2 * j + 1];
206 641040 : dot_prod_real += DFT_L[2 * j] * DFT_R[2 * j] + DFT_L[2 * j + 1] * DFT_R[2 * j + 1];
207 641040 : dot_prod_img += DFT_L[2 * j + 1] * DFT_R[2 * j] - DFT_L[2 * j] * DFT_R[2 * j + 1];
208 : }
209 160260 : sum_nrg_Mid = max( 0.f, sum_nrg_L + sum_nrg_R + 2.f * dot_prod_real );
210 160260 : sum_abs = sqrtf( sum_nrg_L ) + sqrtf( sum_nrg_R ) + EPSILON;
211 160260 : dot_prod_abs = sqrtf( dot_prod_real * dot_prod_real + dot_prod_img * dot_prod_img );
212 160260 : wR = sqrtf( 0.5f * ( sum_nrg_L + sum_nrg_R ) + dot_prod_abs ) / sum_abs;
213 160260 : wL = wR + sqrtf( 2.f ) * ( 1.f - sqrtf( sum_nrg_Mid ) / sum_abs );
214 :
215 801300 : for ( i = hStereoDft->band_limits[b]; i < hStereoDft->band_limits[b + 1]; i++ )
216 : {
217 : /*DMX Mapping*/
218 641040 : pDFT_DMX[2 * i] = ( wL * DFT_L[2 * i] + wR * DFT_R[2 * i] ) * INV_SQRT_2;
219 641040 : pDFT_DMX[2 * i + 1] = ( wL * DFT_L[2 * i + 1] + wR * DFT_R[2 * i + 1] ) * INV_SQRT_2;
220 : }
221 : }
222 :
223 32052 : mvr2r( pDFT_DMX, DFT[0] + k * STEREO_DFT32MS_N_MAX, hStereoDft->NFFT );
224 :
225 : /* Update DFT_past_DMX, needed for stereo filling used by stereo residual PLC */
226 32052 : hStereoDft->past_DMX_pos = ( hStereoDft->past_DMX_pos + 1 ) % STEREO_DFT_PAST_MAX;
227 32052 : mvr2r( pDFT_DMX, hStereoDft->DFT_past_DMX[hStereoDft->past_DMX_pos], min( hStereoDft->NFFT, STEREO_DFT32MS_N_32k ) );
228 :
229 32052 : if ( st0->bfi && !prev_bfi )
230 : {
231 : int16_t idx_k0, idx_k1;
232 1476 : idx_k0 = ( hStereoDft->past_DMX_pos + STEREO_DFT_PAST_MAX - 1 ) % STEREO_DFT_PAST_MAX;
233 1476 : idx_k1 = ( idx_k0 + 1 ) % STEREO_DFT_PAST_MAX;
234 :
235 : /*dmx energy memory*/
236 1476 : hStereoDft->past_dmx_nrg = stereo_dft_dmx_swb_nrg( hStereoDft->DFT_past_DMX[idx_k0], hStereoDft->DFT_past_DMX[idx_k1], min( hStereoDft->NFFT, STEREO_DFT32MS_N_32k ) );
237 : }
238 : }
239 :
240 16026 : return;
241 : }
242 :
243 :
244 : /*-------------------------------------------------------------------*
245 : * add_HB_to_mono_dmx()
246 : *
247 : * add ACELP HB for DFT Stereo mono output with residual coding
248 : *-------------------------------------------------------------------*/
249 :
250 52866 : void add_HB_to_mono_dmx(
251 : CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */
252 : float output[L_FRAME48k], /* i/o: output synthesis */
253 : float outputHB[L_FRAME48k], /* i : HB synthesis */
254 : const int16_t last_core, /* i : last core, primary channel */
255 : const int16_t output_frame /* i : frame length */
256 : )
257 : {
258 : int16_t i, j, decoderDelay, icbweOLASize, dftOvlLen, memOffset;
259 : float temp[L_FRAME48k + NS2SA( 48000, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS )];
260 :
261 : float winSlope;
262 : float alpha;
263 : const float *win_dft;
264 : int32_t output_Fs;
265 : float *memOutHB, *memTransitionHB;
266 :
267 52866 : output_Fs = hCPE->hCoreCoder[0]->output_Fs;
268 52866 : memOutHB = hCPE->hStereoDftDmx->memOutHB;
269 52866 : memTransitionHB = hCPE->hStereoDftDmx->memTransitionHB;
270 :
271 52866 : memOffset = NS2SA( output_Fs, IVAS_DEC_DELAY_NS - DELAY_BWE_TOTAL_NS );
272 :
273 52866 : if ( hCPE->hCoreCoder[0]->core == ACELP_CORE && hCPE->hCoreCoder[0]->extl_brate > 0 )
274 : {
275 : /* Resampled LB and HB offset */
276 33135 : mvr2r( outputHB, temp + memOffset, output_frame - memOffset );
277 :
278 33135 : decoderDelay = NS2SA( output_Fs, IVAS_DEC_DELAY_NS );
279 :
280 33135 : if ( last_core != ACELP_CORE )
281 : {
282 : /* hb_synth of mid band is faded out in the 1.25 ms prior to DFT analysis and the icbwe is faded in time domain */
283 2214 : icbweOLASize = NS2SA( output_Fs, STEREO_DFT_DELAY_DEC_BWE_NS );
284 :
285 299394 : for ( i = 0; i < decoderDelay; i++ )
286 : {
287 297180 : temp[i] = 0;
288 : }
289 :
290 2214 : assert( icbweOLASize > 0 );
291 2214 : winSlope = 1.0f / icbweOLASize;
292 2214 : alpha = winSlope;
293 116514 : for ( ; i < decoderDelay + icbweOLASize; i++ )
294 : {
295 114300 : temp[i] *= alpha;
296 114300 : alpha += winSlope;
297 : }
298 : }
299 : else
300 : {
301 30921 : mvr2r( memOutHB, temp, memOffset );
302 : }
303 :
304 33135 : v_add( temp, output, output, output_frame );
305 :
306 33135 : mvr2r( outputHB + output_frame - memOffset, memOutHB, memOffset );
307 :
308 33135 : win_dft = hCPE->hStereoDft->win32ms;
309 33135 : dftOvlLen = hCPE->hStereoDft->dft32ms_ovl;
310 :
311 : /* Preparing buffers in anticipation of an ACELP to TCX switch */
312 33135 : j = 0;
313 1243455 : for ( i = 0; i < memOffset; i++ )
314 : {
315 1210320 : memTransitionHB[i] = memOutHB[i] * win_dft[STEREO_DFT32MS_STEP * ( dftOvlLen - 1 - j )];
316 1210320 : j++;
317 : }
318 :
319 2857215 : for ( i = 0; j < dftOvlLen; i++ )
320 : {
321 2824080 : memTransitionHB[memOffset + i] = outputHB[output_frame - i - 1] * win_dft[STEREO_DFT32MS_STEP * ( dftOvlLen - 1 - j )];
322 2824080 : j++;
323 : }
324 : }
325 : else
326 : {
327 19731 : if ( last_core == ACELP_CORE )
328 : {
329 : /* This is generated in the ACELP frame and windowed. This process is akin to GenTransition for IC-BWE */
330 7311 : if ( hCPE->element_mode == IVAS_CPE_DFT && hCPE->nchan_out == 1 && hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF )
331 : {
332 3039 : v_add( output, outputHB, output, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) );
333 : }
334 : else
335 : {
336 4272 : v_add( output, memTransitionHB, output, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) );
337 : }
338 :
339 7311 : set_f( memOutHB, 0, memOffset );
340 7311 : set_f( memTransitionHB, 0, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) );
341 : }
342 : }
343 :
344 52866 : return;
345 : }
|