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 : /*====================================================================================
34 : EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
35 : ====================================================================================*/
36 :
37 : #include <stdint.h>
38 : #include "options.h"
39 : #ifdef DEBUGGING
40 : #include "debug.h"
41 : #endif
42 : #include "cnst.h"
43 : #include "ivas_prot.h"
44 : #include "prot.h"
45 : #include "rom_com.h"
46 : #include "rom_enc.h"
47 : #include "basop_proto_func.h"
48 : #include "wmc_auto.h"
49 :
50 :
51 : /*--------------------------------------------------------------------------*
52 : * Local constants
53 : *--------------------------------------------------------------------------*/
54 :
55 : #define kMaxC 8
56 :
57 :
58 : /*--------------------------------------------------------------------------*
59 : * msvq_encmsvq_stage1_dct_search()
60 : *
61 : * stage1 search in a segmentwise truncated dct N domain without weights
62 : *--------------------------------------------------------------------------*/
63 :
64 : /*! r: (p_max , best candidate sofar ) */
65 3088 : int16_t msvq_stage1_dct_search(
66 : const float *u, /* i : target */
67 : const int16_t N, /* i : target length and IDCT synthesis length */
68 : const int16_t maxC_st1, /* i : number of final stage 1 candidates to provide */
69 : const DCTTYPE dcttype, /* e.g. DCT_T2_16_XX, DCT_T2_24_XX; */
70 : const int16_t max_dct_trunc, /* i : maximum of truncation lenghts */
71 : float *invTrfMatrix, /* i : IDCT synthesis matrix for dim N */
72 : const float *midQ_truncQ, /* i : midQ vector */
73 : const float *dct_invScaleF, /* i : global inv scale factors */
74 : const float *dct_scaleF, /* i : global scale factors */
75 : const Word16 n_segm, /* i : number of segments */
76 : const Word16 *cols_per_segment, /* i : remaining length per segment */
77 : const Word16 *trunc_dct_cols_per_segment, /* i : trunc length per segment */
78 : const Word16 *entries_per_segment, /* i : number of rows per segment */
79 : const Word16 *cum_entries_per_segment, /* i : number of cumulative entries */
80 : const Word8 *const W8Qx_dct_sections[], /* i : Word8(byte) segment table ptrs */
81 : const Word16 *col_syn_shift[], /* i : columnwise syn shift tables */
82 : const Word8 *segm_neighbour_fwd, /* i : circular neighbour list fwd */
83 : const Word8 *segm_neighbour_rev, /* i : circular neighbour list reverse */
84 : const Word16 npost_check, /* i : number of neigbours to check , should be even */
85 : float *st1_mse_ptr, /* i : dynRAM buffer for MSEs */
86 : int16_t *indices_st1_local, /* o : selected cand indices */
87 : float *st1_syn_vec_ptr, /* i/o: buffer for IDCT24 synthesis */
88 : float *dist1_ptr /* o : resulting stage 1 MSEs in DCT-N domain */
89 : )
90 : {
91 : float dct_target[FDCNG_VQ_DCT_MAXTRUNC];
92 : float u_mr[FDCNG_VQ_MAX_LEN];
93 : float u_mr_scaled[FDCNG_VQ_MAX_LEN];
94 : float mse_trunc_segm[FDCNG_VQ_DCT_NSEGM];
95 : float tmp, check_mse;
96 : float mse; /* Word32 in BASOP */
97 :
98 : int16_t p_max, c, c2, segm, j_full, j, i;
99 : int16_t n_ana, p_mins[2], idx_min[2];
100 :
101 : const Word8 *cbpW8;
102 : const Word16 *dct_col_shift_tab;
103 :
104 : float *st1_mse_pair;
105 : int16_t *st1_idx_pair;
106 :
107 : float tmp2;
108 : int16_t check_ind[FDCNG_VQ_DCT_NPOST];
109 3088 : assert( ( npost_check % 2 == 0 ) && ( npost_check <= FDCNG_VQ_DCT_NPOST ) );
110 :
111 3088 : assert( n_segm <= FDCNG_VQ_DCT_NSEGM );
112 :
113 3088 : n_ana = N; /* VQ stage#1 core is currently always using stored DCT N coeffs */
114 3088 : assert( n_ana >= max_dct_trunc ); /* check for FDCNGVQ WB , SWB, FB operation */
115 :
116 : /* remove mid stage#1 vector, in original input domain */
117 3088 : v_sub( u, midQ_truncQ, u_mr, n_ana );
118 :
119 3088 : v_multc( u_mr, dct_invScaleF[1], u_mr_scaled, n_ana ); /* scale up target to upscaled W8x storage domain */
120 : /* 16.0-->scale up from Q0 to search domain in Q4, not really needed in BASOP , impl. by shifts */
121 :
122 3088 : dctT2_N_apply_matrix( (const float *) u_mr_scaled, dct_target, min( max_dct_trunc, n_ana ), n_ana, invTrfMatrix, max_dct_trunc, dcttype );
123 :
124 : /* init search state ptr's at the top */
125 3088 : set_f( dist1_ptr, FLT_MAX, maxC_st1 );
126 3088 : st1_mse_pair = &( dist1_ptr[0] ); /* req. ptr post upd +=2 */
127 3088 : st1_idx_pair = &( indices_st1_local[0] ); /* req. ptr post upd +=2 */
128 3088 : set_f( mse_trunc_segm, 0.0f, n_segm );
129 :
130 15440 : for ( segm = 0; segm < n_segm; segm++ )
131 : { /* point to a new paired location for each segment */
132 12352 : p_max = 0; /* req. to point to one of 1 or 0, this init can potentially be omitted here,as p_max is always 1 or 0 */
133 :
134 : /* compute segment common trunction error in dctN domain */
135 12352 : mse_trunc_segm[segm] += sum2_f( (const float *) ( &( dct_target[cols_per_segment[segm]] ) ), trunc_dct_cols_per_segment[segm] );
136 :
137 12352 : cbpW8 = W8Qx_dct_sections[segm]; /* Word8 column variable Qx storage , table ptr init */
138 :
139 407616 : for ( j = 0; j < entries_per_segment[segm]; j++ )
140 : {
141 : /* unweighted segmented search DCT domain loop */
142 395264 : j_full = j + cum_entries_per_segment[segm]; /* or simply use j_full++ */
143 :
144 395264 : mse = mse_trunc_segm[segm]; /* init mse with with common mse truncation part, in BASOP a move32() */
145 :
146 395264 : dct_col_shift_tab = col_syn_shift[segm]; /* ptr init */
147 :
148 6490976 : for ( c2 = 0; c2 < cols_per_segment[segm]; c2++ )
149 : {
150 : #define WMC_TOOL_SKIP
151 6095712 : tmp = dct_target[c2] - (float) shl( (Word16) cbpW8[c2], dct_col_shift_tab[c2] ); /* note: BASOP shift left defined for signed integers */
152 : LOGIC( 1 );
153 : SHIFT( 1 );
154 : ADD( 1 ); /* in BASOP: s_and(for W8->W16), shl(), sub()*/
155 : #undef WMC_TOOL_SKIP
156 6095712 : mse += tmp * tmp; /* L_mac or L_mac0() square Word16 -> Word32*/
157 : }
158 395264 : st1_mse_ptr[j_full] = mse; /* save MSE in shared dynamic RAM, move32() in BASOP */
159 :
160 : #define WMC_TOOL_SKIP
161 395264 : cbpW8 += cols_per_segment[segm]; /* fixed pointer increment for each segment */
162 : #undef WMC_TOOL_SKIP
163 :
164 : /* overwrite with a new worst index at p_max */
165 :
166 : /* Note: The three inner loop if's below are not 100% properly instrumented by WMC tool */
167 395264 : if ( mse < st1_mse_pair[p_max] ) /* L_sub */
168 : {
169 162938 : st1_idx_pair[p_max] = j_full; /* move16, single BASOP */
170 : } /* BASOP 2 ops */
171 :
172 395264 : if ( st1_idx_pair[p_max] == j_full )
173 : { /* idx updated --> also update mse */
174 162938 : st1_mse_pair[p_max] = mse; /* move32(), single BASOP */
175 : } /* BASOP 3 ops */
176 :
177 : /* avoid WC costly candidate list management by always updating p_max,
178 : as we have only a pair in each segment to maintain */
179 395264 : p_max = 0; /* move16() */
180 395264 : if ( ( st1_mse_pair[0] - st1_mse_pair[1] ) < 0 ) /* L_sub()*/
181 : {
182 201646 : p_max = 1; /* move16() */
183 : } /* BASOP 3 ops ,Note 2 ops possible in BASOP with L_sub and L_lshr */
184 :
185 : /* Note: logical shift right not available in ANSI-C */
186 : /* p_max = (st1_mse_pair[0] - st1_mse_pair[1]) ">>>" 31; */
187 : /* in java logical shift right is available as >>> , in BASOP it is available as L_lshr */
188 :
189 : /* Cost: weighted sum with cond moves ('if') => 8 in float , 7 in BASOP with L_lshr */
190 : } /* j in section */
191 :
192 12352 : st1_mse_pair += 2; /* req. ptr init */
193 12352 : st1_idx_pair += 2; /* req. ptr init */
194 :
195 : } /* next segment */
196 :
197 27792 : for ( j = 0; j < maxC_st1; j++ )
198 : {
199 : /* compute_full mse using stored DCT24 domain MSE's */
200 : /* calculate MSE from stage1 inner using existing inner DCT domain variables */
201 24704 : dist1_ptr[j] *= dct_scaleF[2]; /* multiplication to get the DCT inner MSE scale to the correct input domain */
202 : }
203 :
204 3088 : assert( ( maxC_st1 >= 3 ) );
205 3088 : assert( ( maxC_st1 <= 8 ) );
206 :
207 3088 : p_max = maximum( dist1_ptr, maxC_st1, NULL ); /* establish current worst candidate for MSVQ stage#2 among all maxC_st1 candidates so far */
208 :
209 3088 : p_mins[0] = minimum( dist1_ptr, maxC_st1, NULL ); /* find best entry among all maxC_pre */
210 3088 : tmp = dist1_ptr[p_mins[0]];
211 3088 : dist1_ptr[p_mins[0]] = FLT_MAX; /* exclude 1st */
212 :
213 3088 : p_mins[1] = minimum( dist1_ptr, maxC_st1, NULL ); /* find 2nd best entry */
214 3088 : tmp2 = dist1_ptr[p_mins[1]];
215 3088 : dist1_ptr[p_mins[1]] = FLT_MAX; /* exclude 2nd */
216 :
217 3088 : dist1_ptr[p_mins[0]] = tmp; /* restore 1st */
218 3088 : dist1_ptr[p_mins[1]] = tmp2; /* restore 2nd */
219 :
220 3088 : idx_min[0] = indices_st1_local[p_mins[0]];
221 3088 : idx_min[1] = indices_st1_local[p_mins[1]];
222 :
223 :
224 : /* use global exclusion list to never reselect the two (best) global MSE values sofar */
225 3088 : st1_mse_ptr[idx_min[0]] = FLT_MAX; /* move32() */
226 3088 : st1_mse_ptr[idx_min[1]] = FLT_MAX; /* move32() */
227 :
228 : /* circular MSE-neigbour list in use to potentially replace some segment search candidates */
229 : /* using both 1st and 2nd best neighbours in fwd and rev directions */
230 3088 : check_ind[0] = segm_neighbour_fwd[idx_min[0]];
231 3088 : check_ind[1] = segm_neighbour_rev[idx_min[0]];
232 :
233 3088 : check_ind[2] = segm_neighbour_fwd[idx_min[1]];
234 3088 : check_ind[3] = segm_neighbour_rev[idx_min[1]];
235 :
236 3088 : check_ind[4] = segm_neighbour_fwd[check_ind[0]];
237 3088 : check_ind[5] = segm_neighbour_rev[check_ind[1]];
238 :
239 3088 : check_ind[6] = segm_neighbour_fwd[check_ind[2]];
240 3088 : check_ind[FDCNG_VQ_DCT_NPOST - 1] = segm_neighbour_rev[check_ind[3]];
241 :
242 27792 : for ( i = 0; i < npost_check; i++ )
243 : {
244 : /* move MSE from DCT-inner loop search to input synthesis domain */
245 : /* multiplication by fdcng_dct_scaleF[2] to get the float outer loop scale correct in IDCT synthesis domain */
246 24704 : check_mse = st1_mse_ptr[check_ind[i]] * dct_scaleF[2];
247 :
248 24704 : if ( check_mse < dist1_ptr[p_max] )
249 : { /* new winner , replace worst */
250 11929 : dist1_ptr[p_max] = check_mse;
251 11929 : indices_st1_local[p_max] = check_ind[i];
252 11929 : st1_mse_ptr[check_ind[i]] = FLT_MAX; /* exclude, BASOP: move32() */
253 11929 : p_max = maximum( dist1_ptr, maxC_st1, NULL ); /* establish a new current worst candidate among all maxC */
254 : }
255 : }
256 :
257 : /* extract the selected stage one vectors in DCT_N domain , apply IDCT_N and scale up */
258 : /* always extract full length signal(e.g. 24) to be able to update WB(e.g. N_in==21) candidate MSE values */
259 : /* in the case that only a part of the IDCT N vector is in final use */
260 :
261 : /* note: synthesis not yet fully parameterized/generalized for other IDCT lengths */
262 3088 : assert( N == 24 );
263 : {
264 27792 : for ( c = 0; c < maxC_st1; c++ )
265 : {
266 24704 : dec_FDCNG_MSVQ_stage1( indices_st1_local[c], N, invTrfMatrix, dcttype + 1, &( st1_syn_vec_ptr[c * N] ), NULL );
267 : }
268 : }
269 :
270 3088 : return p_max; /*ptr to worst performing candidate */
271 : }
272 :
273 :
274 : /*--------------------------------------------------------------------------*
275 : * msvq_stage1_dct_recalc_candidates_fdcng_wb()
276 : *
277 : * recalc MSE for fdcng WB(0..20) coeffs ,
278 : essentially subtract res21^2 ,res22^2, res23^2 that was included in stage1 MSE in the DCT24 domain truncated search,
279 : excludes the waveform contributions at pos 21,22,23 to the MSE, important to keep the WB MSEs update for the subsequent stages
280 : *--------------------------------------------------------------------------*/
281 :
282 : /*! r: (updated p_max) */
283 888 : int16_t msvq_stage1_dct_recalc_candidates_fdcng_wb(
284 : const float *st1_syn_vec_ptr, /* i : IDCT24 synthesis vectors */
285 : const float *u, /* i : target signal */
286 : const int16_t maxC_st1, /* i : number of candidates in stage1 */
287 : float *dist_ptr /* i/o: updated MSE vector for stage1 */
288 : )
289 : {
290 : int16_t p_max_local, c;
291 : const float *p2;
292 : float res24, high_diff[FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB];
293 :
294 7992 : for ( c = 0; c < maxC_st1; c++ )
295 : { /* point to extended synthesis part */
296 7104 : p2 = (const float *) &( st1_syn_vec_ptr[c * FDCNG_VQ_MAX_LEN + FDCNG_VQ_MAX_LEN_WB] ); /* ptr init to synthesis candidate c */
297 : /* for stage#1 use "u" instead of the shortened resid[0], to access the extended/extrapolated input target */
298 7104 : v_sub( p2, &( u[FDCNG_VQ_MAX_LEN_WB] ), high_diff, FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB );
299 7104 : res24 = dotp( high_diff, high_diff, FDCNG_VQ_MAX_LEN - FDCNG_VQ_MAX_LEN_WB ); /* sum squared over top env. values above WB coeffs */
300 :
301 7104 : dist_ptr[c] -= res24; /* remove DCT24 high band error contribution */
302 : }
303 :
304 : /* finally update p_max, as it may potentially change,
305 : due to the core DCT24 search originally optimizing over the longer basis vectors than DCT21 */
306 888 : p_max_local = maximum( dist_ptr, maxC_st1, NULL );
307 :
308 888 : return p_max_local;
309 : }
310 :
311 :
312 : /*--------------------------------------------------------------------------*
313 : * msvq_enc()
314 : *
315 : * MSVQ encoder
316 : *--------------------------------------------------------------------------*/
317 :
318 126913 : void msvq_enc(
319 : const float *const *cb, /* i : Codebook (indexed cb[*stages][levels][p]) */
320 : const int16_t dims[], /* i : Dimension of each codebook stage (NULL: full dim.) */
321 : const int16_t offs[], /* i : Starting dimension of each codebook stage (NULL: 0) */
322 : const float u[], /* i : Vector to be encoded (prediction and mean removed) */
323 : const int16_t *levels, /* i : Number of levels in each stage */
324 : const int16_t maxC, /* i : Tree search size (number of candidates kept from one stage to the next == M-best) */
325 : const int16_t stages, /* i : Number of stages */
326 : const float w[], /* i : Weights */
327 : const int16_t N, /* i : Vector dimension */
328 : const int16_t maxN, /* i : Codebook dimension */
329 : const int16_t applyDCT_flag, /* i : applyDCT flag */
330 : float *invTrfMatrix, /* i/o: synthesis matrix */
331 : int16_t Idx[] /* o : Indices */
332 : )
333 : {
334 : float *resid[2], *dist[2];
335 : float en, tmp, *pTmp, *p1;
336 : const float *cb_stage, *cbp, *p2;
337 : int16_t *indices[2];
338 : int16_t j, m, s, c, c2, p_max, i;
339 : float resid_buf[2 * LSFMBEST_MAX * M_MAX], dist_buf[2 * LSFMBEST_MAX], Tmp[M_MAX];
340 : int16_t idx_buf[2 * LSFMBEST_MAX * MAX_VQ_STAGES_USED], parents[LSFMBEST_MAX];
341 : int16_t n, maxn, start;
342 : float *st1_syn_vec_ptr; /* ptr to buffer in dynRAM */
343 : float *st1_mse_ptr; /* ptr to buffer in existing dRAM used for stage 1 candidate analysis */
344 : int16_t indices_st1_local[FDCNG_VQ_DCT_NSEGM * 2]; /* after stage#1 DCT search this is copied to the global indices[1][s*stages] structure */
345 126913 : assert( maxC <= LSFMBEST_MAX );
346 126913 : assert( ( LSFMBEST_MAX * M_MAX ) > ( N * maxC ) );
347 : /* top of resid_buf is resid[1] and used for stage#1 residuals (input target u),
348 : we here reuse resid[0] part of the buffer for stage#1 DCT dynamic RAM needs */
349 126913 : st1_mse_ptr = &( resid_buf[1 * LSFMBEST_MAX * M_MAX] ) - ( levels[0] ); /* reuse top of residual resid[0] scratch RAM for stage1 MSEs */
350 :
351 126913 : st1_syn_vec_ptr = &( resid_buf[1 * LSFMBEST_MAX * M_MAX] ) - FDCNG_VQ_MAX_LEN * maxC; /* reuse top of resid[0] scratch RAM for residual */
352 :
353 :
354 : /*----------------------------------------------------------------*
355 : * Allocate memory for previous (parent) and current nodes.
356 : * Parent node is indexed [0], current node is indexed [1].
357 : *----------------------------------------------------------------*/
358 :
359 126913 : indices[0] = idx_buf;
360 126913 : indices[1] = idx_buf + maxC * stages;
361 126913 : set_s( idx_buf, 0, 2 * stages * maxC );
362 :
363 126913 : resid[0] = resid_buf;
364 126913 : pTmp = resid_buf + maxC * N;
365 126913 : resid[1] = pTmp;
366 :
367 126913 : dist[0] = dist_buf;
368 126913 : dist[1] = dist_buf + maxC;
369 126913 : set_s( parents, 0, maxC );
370 :
371 : /* Set up initial distance vector */
372 2179561 : for ( tmp = 0.0, j = 0; j < N; j++ )
373 : {
374 2052648 : tmp += u[j] * u[j] * w[j];
375 : }
376 126913 : set_f( dist[1], tmp, maxC );
377 :
378 : /* Set up initial error (residual) vectors */
379 697662 : for ( c = 0; c < maxC; c++ )
380 : {
381 9879053 : for ( i = 0; i < N; i++ )
382 : {
383 9308304 : *pTmp++ = u[i];
384 : }
385 : }
386 :
387 : /* Loop over all stages */
388 495431 : for ( m = 1, s = 0; s < stages; s++ )
389 : {
390 : /* codebook pointer is set to point to first stage */
391 368518 : cbp = cb[s];
392 : /* Save pointer to beginning of current stage */
393 368518 : cb_stage = cbp;
394 :
395 : /* Set up pointers to parent and current nodes */
396 : #define WMC_TOOL_SKIP
397 368518 : swap( indices[0], indices[1], int16_t * );
398 : MOVE( 3 );
399 368518 : swap( resid[0], resid[1], float * );
400 : MOVE( 3 );
401 368518 : swap( dist[0], dist[1], float * );
402 : MOVE( 3 );
403 : #undef WMC_TOOL_SKIP
404 :
405 : /* p_max points to maximum distortion node (worst of best) */
406 368518 : p_max = 0;
407 :
408 368518 : if ( dims )
409 : {
410 69828 : n = dims[s];
411 69828 : maxn = dims[s];
412 : }
413 : else
414 : {
415 298690 : n = N;
416 298690 : maxn = maxN;
417 : }
418 :
419 368518 : if ( offs )
420 : {
421 69828 : start = offs[s];
422 : }
423 : else
424 : {
425 298690 : start = 0;
426 : }
427 :
428 368518 : set_zero( Tmp, start );
429 368518 : set_zero( Tmp + start + n, N - ( start + n ) );
430 : /* Set distortions to a large value */
431 1911692 : for ( j = 0; j < maxC; j++ )
432 : {
433 1543174 : dist[1][j] = FLT_MAX;
434 : }
435 :
436 368518 : if ( !s && applyDCT_flag != 0 ) /* means: m==1 */
437 : {
438 : /* stage 1 candidates search in truncated dct24 domain without any weights */
439 3088 : assert( N == FDCNG_VQ_MAX_LEN || N == FDCNG_VQ_MAX_LEN_WB ); /* 21 and 24 allowed */
440 3088 : assert( maxC == 2 * FDCNG_VQ_DCT_NSEGM );
441 :
442 3088 : p_max = msvq_stage1_dct_search( u, FDCNG_VQ_MAX_LEN, maxC, DCT_T2_24_XX, FDCNG_VQ_DCT_MAXTRUNC, invTrfMatrix, cdk1r_tr_midQ_truncQ, fdcng_dct_invScaleF, fdcng_dct_scaleF, FDCNG_VQ_DCT_NSEGM,
443 : cdk1_ivas_cols_per_segment, cdk1_ivas_trunc_dct_cols_per_segment, cdk1_ivas_entries_per_segment, cdk1_ivas_cum_entries_per_segment, cdk_37bits_ivas_stage1_W8Qx_dct_sections,
444 : stage1_dct_col_syn_shift, cdk1_ivas_segm_neighbour_fwd, cdk1_ivas_segm_neighbour_rev, FDCNG_VQ_DCT_NPOST, st1_mse_ptr, indices_st1_local, st1_syn_vec_ptr, dist[1] );
445 :
446 :
447 : /* move established stage#1 indices to the global MSVQ list structure */
448 27792 : for ( c = 0; c < maxC; c++ )
449 : {
450 24704 : indices[1][c * stages] = indices_st1_local[c];
451 : }
452 : }
453 : else
454 : /* non-DCT Stage #1 code below */
455 365430 : if ( !s ) /* means: m==1 */
456 : {
457 : /* This loop is identical to the one below, except, that the inner loop over c=0..m is hardcoded to c=0, since m=1. */
458 : /* dist[0][0] */
459 8689653 : for ( j = 0; j < levels[s]; j++ )
460 : {
461 8565828 : en = 0.0f;
462 : /* w,Tmp */
463 : /* Compute weighted codebook element and its energy */
464 144641484 : for ( c2 = 0; c2 < n; c2++ )
465 : {
466 136075656 : Tmp[start + c2] = w[start + c2] * cbp[c2];
467 136075656 : en += cbp[c2] * Tmp[start + c2];
468 : }
469 8565828 : cbp += maxn; /* pointer is incremented */
470 :
471 8565828 : pTmp = &resid[0][0];
472 : /* Tmp */
473 8565828 : tmp = ( *pTmp++ ) * Tmp[0];
474 137053248 : for ( c2 = 1; c2 < N; c2++ )
475 : {
476 128487420 : tmp += ( *pTmp++ ) * Tmp[c2];
477 : }
478 8565828 : tmp = en - 2.0f * tmp;
479 8565828 : tmp += dist[0][0];
480 8565828 : if ( tmp < dist[1][p_max] )
481 : {
482 : /* Replace worst */
483 1574549 : dist[1][p_max] = tmp;
484 1574549 : indices[1][p_max * stages] = j;
485 1574549 : parents[p_max] = 0;
486 :
487 1574549 : p_max = 0;
488 6623762 : for ( c2 = 1; c2 < maxC; c2++ )
489 : {
490 5049213 : if ( dist[1][c2] > dist[1][p_max] )
491 : {
492 1690979 : p_max = c2;
493 : }
494 : }
495 : } /* if (tmp <= dist[1][p_max]) */
496 : } /* for (j=0; j<levels[s]; j++) */
497 : /* update p_max location , for next stage */
498 123825 : p_max = maximum( dist[1], maxC, NULL );
499 : }
500 : else
501 : {
502 : /* subsequent stages after first stage */
503 : /* dist[0][0] */
504 9377629 : for ( j = 0; j < levels[s]; j++ )
505 : {
506 9136024 : en = 0.0f;
507 : /* w,Tmp */
508 : /* Compute weighted codebook element and its energy */
509 157533592 : for ( c2 = 0; c2 < n; c2++ )
510 : {
511 148397568 : Tmp[start + c2] = w[start + c2] * cbp[c2];
512 148397568 : en += cbp[c2] * Tmp[start + c2];
513 : }
514 9136024 : cbp += maxn; /* pointer is incremented */
515 :
516 : /* dist[0][0] */
517 9136024 : pTmp = &resid[0][0];
518 : /* Iterate over all parent nodes */
519 44011776 : for ( c = 0; c < m; c++ )
520 : {
521 : /* Tmp[0] */
522 34875752 : tmp = ( *pTmp++ ) * Tmp[0];
523 611533440 : for ( c2 = 1; c2 < N; c2++ )
524 : {
525 576657688 : tmp += ( *pTmp++ ) * Tmp[c2];
526 : }
527 34875752 : tmp = en - 2.0f * tmp;
528 34875752 : tmp += dist[0][c];
529 34875752 : if ( tmp < dist[1][p_max] )
530 : {
531 : /* Replace worst */
532 4442099 : dist[1][p_max] = tmp;
533 4442099 : indices[1][p_max * stages + s] = j;
534 4442099 : parents[p_max] = c;
535 :
536 4442099 : p_max = 0;
537 22111502 : for ( c2 = 1; c2 < maxC; c2++ )
538 : {
539 17669403 : if ( dist[1][c2] > dist[1][p_max] )
540 : {
541 5443201 : p_max = c2;
542 : }
543 : }
544 : } /* if (tmp <= dist[1][p_max]) */
545 : } /* for(c=0; c<m; c++) */
546 : } /* for (j=0; j<levels[s]; j++) */
547 : }
548 :
549 : /*------------------------------------------------------------*
550 : * Compute error vectors for each node
551 : *------------------------------------------------------------*/
552 : /* parents[0] */
553 368518 : pTmp = resid[1];
554 1911692 : for ( c = 0; c < maxC; c++ )
555 : {
556 : /* Subtract codebook entry from residual vector of parent node */
557 1543174 : p1 = resid[0] + parents[c] * N;
558 1543174 : p2 = NULL;
559 1543174 : if ( cb_stage != NULL )
560 : {
561 1518470 : p2 = cb_stage + ( indices[1][c * stages + s] ) * maxn; /* regular ptr init */
562 : }
563 1543174 : if ( s == 0 && applyDCT_flag != 0 )
564 : {
565 24704 : p2 = (const float *) &( st1_syn_vec_ptr[c * FDCNG_VQ_MAX_LEN] ); /*ptr init of stage 1 */
566 : }
567 :
568 1543174 : mvr2r( p1, pTmp, start );
569 23056870 : for ( j = 0; j < n; j++ )
570 : {
571 21513696 : pTmp[start + j] = ( p1[start + j] - p2[j] );
572 : }
573 1543174 : mvr2r( p1 + start + n, pTmp + start + n, N - ( start + n ) );
574 1543174 : pTmp += N; /* pointer is incremented */
575 :
576 : /* Get indices that were used for parent node */
577 1543174 : mvs2s( indices[0] + parents[c] * stages, indices[1] + c * stages, s );
578 : } /* for (c=0; c<maxC; c++) */
579 :
580 : /* recalc MSE for WB(0..20) coeffs ,
581 : essentially subtract res21^2 ,res22^2, res23^2 that was included in stage1 MSE in the DCT24 domain truncated search,
582 : excludes the waveform contributions at pos 21,22,23 to the MSE, important to keep WB MSEs update for the subsequent stages
583 : */
584 368518 : if ( s == 0 && applyDCT_flag != 0 && n == FDCNG_VQ_MAX_LEN_WB )
585 : {
586 888 : p_max = msvq_stage1_dct_recalc_candidates_fdcng_wb( st1_syn_vec_ptr, u, maxC, dist[1] );
587 : }
588 368518 : m = maxC;
589 : } /* for (m=1, s=0; s<stages; s++) */
590 :
591 : /* Find the optimum candidate */
592 126913 : c2 = minimum( dist[1], maxC, 0 );
593 126913 : mvs2s( indices[1] + c2 * stages, Idx, stages );
594 :
595 126913 : return;
596 : }
597 :
598 : /*--------------------------------------------------------------------------*
599 : * lsf_msvq_ma_encprm()
600 : *
601 : *
602 : *--------------------------------------------------------------------------*/
603 :
604 111839 : int16_t lsf_msvq_ma_encprm(
605 : BSTR_ENC_HANDLE hBstr,
606 : const int16_t *param_lpc,
607 : const int16_t core,
608 : const int16_t acelp_mode,
609 : const int16_t acelp_midLpc,
610 : const int16_t bits_param_lpc[],
611 : const int16_t no_indices )
612 : {
613 : int16_t i, nbits_lpc, bits_midlpc;
614 :
615 111839 : bits_midlpc = MIDLSF_NBITS;
616 :
617 111839 : nbits_lpc = 0;
618 459980 : for ( i = 0; i < no_indices; i++ )
619 : {
620 348141 : push_next_indice( hBstr, *param_lpc, bits_param_lpc[i] );
621 348141 : param_lpc++;
622 348141 : nbits_lpc += bits_param_lpc[i];
623 : }
624 111839 : if ( acelp_mode != VOICED )
625 : {
626 88191 : if ( core == ACELP_CORE && acelp_midLpc )
627 : {
628 336 : push_next_indice( hBstr, *param_lpc, bits_midlpc );
629 336 : nbits_lpc += bits_midlpc;
630 : }
631 : }
632 :
633 111839 : return nbits_lpc;
634 : }
635 :
636 : /*--------------------------------------------------------------------------*
637 : * midlsf_enc()
638 : *
639 : *
640 : *--------------------------------------------------------------------------*/
641 :
642 717 : void midlsf_enc(
643 : const float qlsf0[],
644 : const float qlsf1[],
645 : const float lsf[],
646 : int16_t *idx,
647 : const int16_t N,
648 : const float *Bin_Ener,
649 : const int16_t narrowBand,
650 : const int32_t sr_core,
651 : const int16_t coder_type )
652 : {
653 : float pred[M], wghts[M], err, err_min, tmp;
654 : int16_t NS, j, k;
655 717 : const float *ratio = NULL;
656 :
657 : /* Select codebook */
658 717 : if ( coder_type == UNVOICED )
659 : {
660 26 : ratio = tbl_mid_unv_wb_5b;
661 : }
662 : else
663 : {
664 691 : ratio = tbl_mid_gen_wb_5b;
665 : }
666 717 : NS = 32;
667 :
668 : /* Weights */
669 717 : Unified_weighting( Bin_Ener, lsf, wghts, narrowBand, coder_type == UNVOICED, sr_core, M );
670 717 : err_min = FLT_MAX;
671 717 : *idx = 0;
672 23661 : for ( k = 0; k < NS; k++ )
673 : {
674 22944 : err = 0;
675 :
676 390048 : for ( j = 0; j < N; j++ )
677 : {
678 367104 : pred[j] = ( 1.0f - ratio[k * N + j] ) * qlsf0[j] + ratio[k * N + j] * qlsf1[j];
679 :
680 367104 : if ( j > 0 && j < N && pred[j] < pred[j - 1] + LSF_GAP_MID )
681 : {
682 2179 : pred[j] = pred[j - 1] + LSF_GAP_MID;
683 : }
684 :
685 367104 : tmp = lsf[j] - pred[j];
686 367104 : err += wghts[j] * tmp * tmp;
687 : }
688 :
689 22944 : if ( err < err_min )
690 : {
691 2864 : err_min = err;
692 2864 : *idx = k;
693 : }
694 : }
695 :
696 717 : return;
697 : }
698 :
699 :
700 : /*--------------------------------------------------------------------------*
701 : * Q_lsf_tcxlpc()
702 : *
703 : *
704 : *--------------------------------------------------------------------------*/
705 :
706 : /*! r: number of indices */
707 17457 : int16_t Q_lsf_tcxlpc(
708 : /* const */ float lsf[], /* i : original lsf */
709 : float lsf_q[], /* o : quantized lsf */
710 : Word16 lsp_q_ind[], /* o : quantized lsp (w/o MA prediction) */
711 : int16_t indices[], /* o : VQ indices */
712 : const int16_t narrowband, /* i : narrowband flag */
713 : const int16_t cdk, /* i : codebook selector */
714 : const float mem_MA[], /* i : MA memory */
715 : const int16_t coder_type, /* i : acelp extended mode */
716 : const float *Bin_Ener /* i : Spectrum energy */
717 : )
718 : {
719 : float weights[M];
720 : float pred[M16k];
721 : int16_t i, NumIndices;
722 : const float *means;
723 : Word16 lsf_q_ind[M16k];
724 : float lsf_rem[M];
725 : float lsf_rem_q[M];
726 : Word16 lsf_rem_q_ind[M];
727 :
728 17457 : Unified_weighting( &Bin_Ener[L_FFT / 2], lsf, weights, narrowband, coder_type == UNVOICED, 12800, M );
729 :
730 17457 : NumIndices = 0;
731 :
732 : /* Put disabled flag */
733 17457 : indices[NumIndices++] = 0;
734 :
735 : /* Inter-frame prediction */
736 17457 : means = lsf_means[narrowband];
737 296769 : for ( i = 0; i < M; ++i )
738 : {
739 279312 : pred[i] = means[i] + MU_MA * mem_MA[i];
740 : }
741 :
742 : /* Subtract prediction */
743 296769 : for ( i = 0; i < M; ++i )
744 : {
745 279312 : lsf[i] -= pred[i];
746 : }
747 :
748 :
749 17457 : msvq_enc( lsf_codebook[narrowband][cdk], lsf_dims, lsf_offs, lsf, lsf_numlevels, kMaxC, TCXLPC_NUMSTAGES, weights, M, M, 0, NULL, indices + NumIndices );
750 17457 : msvq_dec( lsf_codebook[narrowband][cdk], lsf_dims, lsf_offs, TCXLPC_NUMSTAGES, M, M, indices + NumIndices, 0, NULL, lsf_q, lsf_q_ind );
751 :
752 17457 : NumIndices += TCXLPC_NUMSTAGES;
753 :
754 : /* Update flag */
755 17457 : indices[0] = lsf_ind_is_active( lsf_q_ind, lsf_means[narrowband], narrowband, cdk );
756 :
757 : /* Get residual vector */
758 296769 : for ( i = 0; i < M; ++i )
759 : {
760 279312 : lsf_rem[i] = ( pred[i] + lsf[i] ) - ( lsf_means[narrowband][i] + lsf_q_ind[i] / (float) ( 2.0f * 1.28f ) );
761 : }
762 : /* Quantize using extra stage(s) */
763 17457 : msvq_enc( lsf_ind_codebook[narrowband][cdk], lsf_ind_dims, lsf_ind_offs, lsf_rem, lsf_ind_numlevels, kMaxC, TCXLPC_IND_NUMSTAGES, weights, M, M, 0, NULL, indices + NumIndices );
764 :
765 : /* Only add contribution if flag is enabled */
766 17457 : if ( indices[0] )
767 : {
768 : /* Decode */
769 4832 : msvq_dec( lsf_ind_codebook[narrowband][cdk], lsf_ind_dims, lsf_ind_offs, TCXLPC_IND_NUMSTAGES, M, M, indices + NumIndices, 0, NULL, lsf_rem_q, lsf_rem_q_ind );
770 4832 : NumIndices += TCXLPC_IND_NUMSTAGES;
771 :
772 : /* Add to MA-removed vector */
773 82144 : for ( i = 0; i < M; ++i )
774 : {
775 77312 : lsf_q_ind[i] = add( lsf_q_ind[i], lsf_rem_q_ind[i] );
776 : }
777 : }
778 :
779 : /* Add inter-frame prediction */
780 296769 : for ( i = 0; i < M; ++i )
781 : {
782 279312 : lsf_q[i] += pred[i];
783 279312 : lsf[i] += pred[i];
784 : }
785 :
786 17457 : reorder_lsf( lsf_q, TCXLPC_LSF_GAP, M, INT_FS_12k8 );
787 296769 : for ( i = 0; i < M; ++i )
788 : {
789 279312 : lsf_q_ind[i] = add( lsf_q_ind[i], LSFM( lsf_means[narrowband][i] ) );
790 279312 : move16();
791 : }
792 :
793 17457 : basop_reorder_lsf( lsf_q_ind, LSF_GAP_VAL( TCXLPC_LSF_GAP ), M, INT_FS_FX );
794 17457 : if ( lsp_q_ind )
795 : {
796 17457 : basop_lsf2lsp( lsf_q_ind, lsp_q_ind );
797 : }
798 :
799 17457 : return NumIndices;
800 : }
801 :
802 :
803 : /*--------------------------------------------------------------------------*
804 : * enc_lsf_tcxlpc()
805 : *
806 : *
807 : *--------------------------------------------------------------------------*/
808 :
809 : /*! r: number of bits written */
810 17457 : int16_t enc_lsf_tcxlpc(
811 : const int16_t **indices, /* i : Ptr to VQ indices */
812 : BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */
813 : )
814 : {
815 : int16_t i, NumBits, flag;
816 :
817 : /* Read flag */
818 17457 : flag = ( *indices )[0];
819 17457 : ++*indices;
820 :
821 17457 : NumBits = TCXLPC_NUMBITS;
822 69828 : for ( i = 0; i < TCXLPC_NUMSTAGES; ++i )
823 : {
824 52371 : push_next_indice( hBstr, **indices, lsf_numbits[i] );
825 52371 : ++*indices;
826 : }
827 17457 : if ( flag )
828 : {
829 4832 : NumBits += TCXLPC_IND_NUMBITS;
830 9664 : for ( i = 0; i < TCXLPC_IND_NUMSTAGES; ++i )
831 : {
832 4832 : push_next_indice( hBstr, **indices, lsf_ind_numbits[i] );
833 4832 : ++*indices;
834 : }
835 : }
836 :
837 17457 : return NumBits;
838 : }
839 :
840 :
841 : /*--------------------------------------------------------------------------*
842 : * lsf_bctcvq_encprm()
843 : *
844 : *
845 : *--------------------------------------------------------------------------*/
846 :
847 268 : int16_t lsf_bctcvq_encprm(
848 : BSTR_ENC_HANDLE hBstr,
849 : const int16_t *param_lpc,
850 : const int16_t *bits_param_lpc,
851 : const int16_t no_indices )
852 : {
853 : int16_t i, nbits_lpc;
854 :
855 268 : nbits_lpc = 0;
856 :
857 2948 : for ( i = 0; i < no_indices; i++ )
858 : {
859 2680 : push_next_indice( hBstr, *param_lpc, bits_param_lpc[i] );
860 2680 : param_lpc++;
861 2680 : nbits_lpc += bits_param_lpc[i];
862 : }
863 :
864 268 : return nbits_lpc;
865 : }
|