Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdint.h>
6 : #include <assert.h>
7 : #include "options.h" /* Compilation switches */
8 : #include "cnst.h" /* Common constants */
9 : #include "rom_enc.h"
10 : #include "rom_com.h"
11 : #include "prot_fx.h" /* Function prototypes */
12 : #include "prot_fx_enc.h" /* Function prototypes */
13 :
14 :
15 : /*--------------------------------------------------------------------------
16 : * Local function prototypes
17 : *--------------------------------------------------------------------------*/
18 :
19 : static void quant_peaks_fx( BSTR_ENC_HANDLE hBstr, const Word32 *, Word32 *, const Word32 *, Word16 *, const Word16, const Word32, const Word16 );
20 : static Word16 hvq_code_pos_fx( BSTR_ENC_HANDLE hBstr, const Word16 *inp, const Word16 length, const Word16 num_peaks );
21 : static Word16 sparse_code_pos_fx( const Word16 *inp, const Word16 length, Word16 *result );
22 : static Word16 hvq_code_pos_ivas_fx( BSTR_ENC_HANDLE hBstr, const Word16 *inp, const Word16 length, const Word16 num_peaks );
23 :
24 : static void quant_peaks_ivas_fx(
25 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle*/
26 : const Word32 *vect_in, /* i : Target vector in Q12 */
27 : Word32 *vect_out, /* i/o: Quantized vector in Q12 */
28 : const Word32 *peak_gain, /* i : Peak gain vector in Q12 */
29 : Word16 *vq_idx, /* o : Codebook index */
30 : const Word16 overlap, /* i : Overlap indicator */
31 : const Word32 core_brate, /* i : Core bitrate */
32 : const Word16 Npeaks /* i : Number of peaks */
33 : );
34 :
35 :
36 : /*--------------------------------------------------------------------------
37 : * peak_vq_enc_fx()
38 : *
39 : * Vector Quantization of MDCT peaks
40 : *--------------------------------------------------------------------------*/
41 :
42 1467 : Word16 peak_vq_enc_ivas_fx(
43 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
44 : const Word16 bwidth, /* i : audio bandwidth */
45 : const Word32 *coefs, /* i : Input coefficient vector Q12 */
46 : Word32 *coefs_out, /* o : Quantized output vector Q12 */
47 : const Word32 core_brate, /* i : Core bitrate */
48 : const Word16 num_bits, /* i : Number of bits for HVQ */
49 : const Word16 vq_peaks, /* i : Number of identified peaks */
50 : const Word16 *ynrm, /* i : Envelope coefficients */
51 : Word16 *R, /* i/o: Bit allocation/updated bit allocation */
52 : Word16 *vq_peak_idx, /* i : Peak index vector */
53 : Word32 *nf_gains /* i : Estimated noise floor gains Q12 */
54 : )
55 : {
56 : Word16 pos_bits;
57 : Word32 normq;
58 : Word32 pgain_q[HVQ_MAX_PEAKS];
59 : Word32 peak_gains[HVQ_MAX_PEAKS];
60 : Word16 coefs_pvq[HVQ_PVQ_BUF_LEN], *pCoefsPvq; /* Q12 */
61 : Word32 pvq_vector[HVQ_PVQ_BUF_LEN], *pPvqVector;
62 : Word32 *pPvqVectorBandStart;
63 : Word16 pvq_vector_norm[HVQ_PVQ_BUF_LEN];
64 : Word16 fg_pred[NB_SFM_MAX];
65 : Word16 i, j, k, m, r, pvq_bands, num_overlap_bins;
66 : Word16 hcode_l, FlagN, low_peak_bin, vq_cb_idx, max_peaks, bin_th, bin_th2;
67 : Word16 bits;
68 : Word16 nf_seed;
69 : Word16 pgain_cb_idx[HVQ_MAX_PEAKS], pgain_difidx[HVQ_MAX_PEAKS]; /* Q0 */
70 : Word16 pvq_norm[MAX_PVQ_BANDS];
71 : Word16 pvq_bits, bit_budget;
72 : Word16 pos_vec[HVQ_THRES_BIN_32k];
73 : Word16 npulses[MAX_PVQ_BANDS];
74 : Word16 pvq_inp_vector[HVQ_PVQ_BUF_LEN];
75 : Word16 k_sort[MAX_PVQ_BANDS];
76 : Word16 Rk[MAX_PVQ_BANDS];
77 : Word16 gopt[NB_SFM];
78 : Word16 tmp1, exp1;
79 : Word16 Q_coefs;
80 :
81 :
82 : Word16 indx, vqPeaksMinus1, tmp16, whiteNoise;
83 : Word16 *pPgainDifIdx, *pPgainCbIdx, *pVqPeakIdx, *pPosVec;
84 : Word32 *pPeakGains, *pCoefsOut;
85 : const Word32 *pCoefs;
86 : Word32 acc;
87 : UWord16 dontCare16;
88 : Word32 manE_peak, manPeakGains, manPkEnrg; /* Due to very wide dynamic range, use floating point format, i.e., (man, exp) */
89 : Word16 expE_peak, expPeakGains, expPkEnrg;
90 : Word16 *pSelBnds;
91 : Word16 sel_bnds[HVQ_NUM_SFM_24k];
92 : Word16 hvq_band_end[MAX_PVQ_BANDS];
93 : Word16 hvq_band_start[MAX_PVQ_BANDS];
94 : Word16 hvq_band_width[MAX_PVQ_BANDS];
95 : Word16 n_sel_bnds;
96 : UWord32 lsb;
97 :
98 1467 : assert( ( core_brate > HQ_16k40 && core_brate <= HQ_48k ) && "HVQ rate not supported" );
99 :
100 :
101 1467 : max_peaks = extract_l( Mpy_32_32( L_add( imult3216( core_brate, HVQ_PEAKS_PER_DELTA ), HVQ_PEAKS_PER_DELTA_OFFS ), 282564 ) ); /* 1/HVQ_PEAKS_BPS_DELTA in Q31 */
102 :
103 1467 : bits = 0;
104 1467 : move16();
105 1467 : nf_seed = RANDOM_INITSEED;
106 1467 : move16();
107 :
108 :
109 1467 : set16_fx( coefs_pvq, 0, HVQ_PVQ_BUF_LEN );
110 1467 : set32_fx( pvq_vector, 0, HVQ_PVQ_BUF_LEN );
111 1467 : set16_fx( pvq_vector_norm, 0, HVQ_PVQ_BUF_LEN );
112 1467 : set16_fx( npulses, 0, MAX_PVQ_BANDS );
113 :
114 1467 : bin_th = HVQ_THRES_BIN_32k;
115 1467 : move16();
116 1467 : bin_th2 = HVQ_THRES_BIN_32k / HVQ_NF_GROUPS;
117 1467 : move16();
118 : /* Set bit-rate dependent variables */
119 1467 : IF( LT_32( core_brate, HQ_BWE_CROSSOVER_BRATE ) )
120 : {
121 854 : bin_th = HVQ_THRES_BIN_24k;
122 854 : move16();
123 854 : bin_th2 = HVQ_THRES_BIN_24k / HVQ_NF_GROUPS;
124 854 : move16();
125 : }
126 :
127 388923 : FOR( i = 0; i < bin_th; i++ )
128 : {
129 387456 : pos_vec[i] = 0;
130 387456 : move16();
131 : }
132 :
133 : /* Quantize noise floor gains */
134 4401 : FOR( i = 0; i < HVQ_NF_GROUPS; i++ )
135 : {
136 2934 : logqnorm_ivas_fx( &nf_gains[i], 12, &indx, 32, 1, &thren_HQ_fx[0] );
137 :
138 : /* De-quantization */
139 2934 : acc = dicn_fx[indx]; /* Q14 */
140 2934 : move32();
141 2934 : nf_gains[i] = L_shr( acc, 1 + 2 ); /* nf_gains in Q12. dicn_fx is in Q14. Need extra shift +2. */
142 2934 : move32();
143 :
144 2934 : push_indice( hBstr, IND_HVQ_NF_GAIN, indx, 5 );
145 2934 : bits = add( bits, 5 );
146 : }
147 :
148 : /* Signal number of peaks */
149 1467 : i = sub( max_peaks, vq_peaks );
150 1467 : push_indice( hBstr, IND_NUM_PEAKS, i, 5 );
151 1467 : bits = add( bits, 5 );
152 :
153 : /* Identify position of first peak and arrange peak gains by position */
154 1467 : pVqPeakIdx = &vq_peak_idx[0];
155 1467 : low_peak_bin = bin_th;
156 1467 : move16();
157 26502 : FOR( i = 0; i < vq_peaks; i++ )
158 : {
159 25035 : indx = *pVqPeakIdx++;
160 25035 : move16();
161 25035 : IF( LT_16( indx, low_peak_bin ) )
162 : {
163 4294 : low_peak_bin = indx;
164 4294 : move16();
165 : }
166 : /* Store the sign information. */
167 25035 : IF( coefs[indx] < 0 )
168 : {
169 12700 : pos_vec[indx] = -1; /* Negative. */
170 12700 : move16();
171 : }
172 : ELSE
173 : {
174 12335 : pos_vec[indx] = 1; /* Positive */
175 12335 : move16();
176 : }
177 : }
178 :
179 1467 : pPeakGains = &peak_gains[0];
180 1467 : pVqPeakIdx = &vq_peak_idx[0];
181 1467 : pPosVec = &pos_vec[0];
182 1467 : pCoefs = &coefs[0];
183 388923 : FOR( i = 0; i < bin_th; i++ )
184 : {
185 387456 : acc = *pCoefs++;
186 387456 : move32();
187 387456 : IF( *pPosVec++ != 0 )
188 : {
189 25035 : *pPeakGains++ = L_abs( acc ); /* in Q12 */
190 25035 : move32();
191 25035 : *pVqPeakIdx++ = i;
192 25035 : move16();
193 : }
194 : }
195 :
196 : /* Scale down peak gains */
197 : /* Divided by 4 is equivalent to consider peak_gains to be in Q14 from Q12.
198 : * No physical bit shift is actually required.
199 : */
200 :
201 : /* Quantize peak gains */
202 1467 : pPeakGains = &peak_gains[0];
203 1467 : pPgainCbIdx = &pgain_cb_idx[0];
204 1467 : logqnorm_ivas_fx( pPeakGains++, 14, pPgainCbIdx++, 32, 1, &thren_pg_fx[0] );
205 1467 : vqPeaksMinus1 = sub( vq_peaks, 1 );
206 25035 : FOR( i = 0; i < vqPeaksMinus1; i++ )
207 : {
208 23568 : logqnorm_ivas_fx( pPeakGains++, 14, pPgainCbIdx++, 45, 1, &thren_pg_fx[0] );
209 : }
210 :
211 : /* Code quantized peak gain indices
212 : * and also scale up peak gains. */
213 1467 : diffcod_fx( vq_peaks, pgain_cb_idx, &pgain_difidx[1] );
214 : /* Accumulate peak energy. */
215 1467 : manE_peak = L_deposit_l( 0 );
216 1467 : expE_peak = 32;
217 1467 : move16();
218 26502 : FOR( i = 0; i < vq_peaks; i++ )
219 : {
220 25035 : indx = pgain_cb_idx[i];
221 25035 : move16();
222 : /* Scale up peak gains */
223 25035 : pgain_q[i] = L_shl( dicn_pg_fx[indx], 2 ); /* pgain_q in Q12 */
224 25035 : move32();
225 : /* Use floating point operation to deal with wide dynamic range.l
226 : * 32-bit mantissa is used here. It should be even more accurate than
227 : * the floating-point reference code with 24-bit mantissa! */
228 25035 : expPeakGains = norm_l( pgain_q[i] );
229 25035 : manPeakGains = L_shl( pgain_q[i], expPeakGains );
230 25035 : Mpy_32_32_ss( manPeakGains, manPeakGains, &manPkEnrg, &lsb ); /* peak_gains square */
231 25035 : expPkEnrg = shl( expPeakGains, 1 ); /* Multiply by 2 due to squaring. */
232 : /* True floating value = manPkEng x 2^(32 - 1 - expPkEnrg - 2*12).
233 : * In this context, the 32-bit manPkEng is in Q0.
234 : * 32 is due to Mpy_32_32() only providing the 32 MSBs of the 64 bits product.
235 : * -1 is due fractional mode Multiply. 2*12 is due to square of Q12. */
236 25035 : floating_point_add( &manE_peak, &expE_peak, manPkEnrg, expPkEnrg );
237 : }
238 1467 : pgain_difidx[0] = pgain_cb_idx[0];
239 1467 : move16();
240 :
241 : /* Huffman coding */
242 1467 : hcode_l = 0;
243 1467 : move16();
244 1467 : pPgainDifIdx = &pgain_difidx[1];
245 25035 : FOR( i = 0; i < vqPeaksMinus1; i++ )
246 : {
247 23568 : indx = *pPgainDifIdx++;
248 23568 : move16();
249 23568 : hcode_l = add( hcode_l, pgain_huffsizn[indx] );
250 : }
251 :
252 1467 : FlagN = HUFCODE;
253 1467 : move16();
254 :
255 1467 : tmp16 = extract_l( L_mult0( GAINI_BITS, vqPeaksMinus1 ) );
256 1467 : IF( GE_16( hcode_l, tmp16 ) )
257 : {
258 25 : hcode_l = tmp16;
259 25 : move16();
260 25 : FlagN = NOHUFCODE;
261 25 : move16();
262 : }
263 :
264 1467 : push_indice( hBstr, IND_FLAGN, FlagN, 1 );
265 1467 : push_indice( hBstr, IND_PG_IDX, pgain_difidx[0], GAIN0_BITS );
266 :
267 1467 : IF( FlagN )
268 : {
269 1442 : pPgainDifIdx = &pgain_difidx[1];
270 24645 : FOR( i = 0; i < vqPeaksMinus1; i++ )
271 : {
272 23203 : j = *pPgainDifIdx++;
273 23203 : move16();
274 23203 : m = pgain_huffnorm[j];
275 23203 : move16();
276 23203 : r = pgain_huffsizn[j];
277 23203 : move16();
278 :
279 23203 : push_indice( hBstr, IND_PG_IDX, m, r );
280 : }
281 : }
282 : ELSE
283 : {
284 25 : pPgainDifIdx = &pgain_difidx[1];
285 390 : FOR( i = 0; i < vqPeaksMinus1; i++ )
286 : {
287 365 : push_indice( hBstr, IND_PG_IDX, ( *pPgainDifIdx++ ), GAINI_BITS );
288 : }
289 : }
290 :
291 : /* Number of bits used for peak gain quantization */
292 1467 : bits = add( bits, add( FLAGN_BITS + GAIN0_BITS, hcode_l ) );
293 :
294 : /* Add sign for peak shape normalization */
295 26502 : FOR( i = 0; i < vq_peaks; i++ )
296 : {
297 25035 : indx = vq_peak_idx[i];
298 25035 : move16();
299 25035 : peak_gains[i] = pgain_q[i]; /* Q12 */
300 25035 : move32();
301 25035 : IF( pos_vec[indx] < 0 )
302 : {
303 12700 : peak_gains[i] = L_negate( peak_gains[i] ); /* Q12 */
304 12700 : move32();
305 : }
306 : }
307 :
308 : /* Quantize peak shapes */
309 25035 : FOR( i = 0; i < vqPeaksMinus1; i++ )
310 : {
311 23568 : num_overlap_bins = sub( 5, sub( vq_peak_idx[i + 1], vq_peak_idx[i] ) );
312 23568 : indx = sub( vq_peak_idx[i], 2 );
313 23568 : quant_peaks_ivas_fx( hBstr, &coefs[indx], &coefs_out[indx], &peak_gains[i], &vq_cb_idx, num_overlap_bins, core_brate, vq_peaks );
314 23568 : push_indice( hBstr, IND_HVQ_PEAKS, vq_cb_idx, 8 );
315 23568 : bits = add( bits, 9 );
316 : }
317 :
318 1467 : indx = sub( vq_peak_idx[i], 2 );
319 1467 : quant_peaks_ivas_fx( hBstr, &coefs[indx], &coefs_out[indx], &peak_gains[i], &vq_cb_idx, 0, core_brate, vq_peaks );
320 1467 : push_indice( hBstr, IND_HVQ_PEAKS, vq_cb_idx, 8 );
321 1467 : bits = add( bits, 9 );
322 :
323 : /* Quantize peak positions and sign with HVQ */
324 1467 : pos_bits = hvq_code_pos_ivas_fx( hBstr, pos_vec, bin_th, vq_peaks );
325 :
326 1467 : bits = add( bits, pos_bits );
327 1467 : bit_budget = sub( num_bits, bits );
328 :
329 : /* Calculate number of PVQ bands to code and assign bits */
330 1467 : pvq_bands = hvq_pvq_bitalloc_fx( bit_budget, core_brate, bwidth, ynrm, manE_peak, expE_peak, Rk, R, sel_bnds, &n_sel_bnds );
331 :
332 : /* Get band limits for concatenated PVQ target */
333 1467 : hvq_concat_bands_fx( pvq_bands, sel_bnds, n_sel_bnds, hvq_band_start, hvq_band_width, hvq_band_end );
334 :
335 : /* Quantize PVQ bands */
336 1467 : pCoefsOut = coefs_out;
337 1467 : pCoefs = coefs;
338 1467 : pPvqVector = pvq_vector;
339 1467 : pSelBnds = sel_bnds;
340 1467 : m = bin_th;
341 1467 : move16();
342 4317 : FOR( k = 0; k < pvq_bands; k++ )
343 : {
344 2850 : IF( GE_16( k, sub( pvq_bands, n_sel_bnds ) ) )
345 : {
346 369 : i = band_start_harm[*pSelBnds++];
347 369 : move16();
348 369 : pCoefs = coefs + i;
349 369 : pCoefsOut = coefs_out + i;
350 : }
351 2850 : k_sort[k] = k;
352 2850 : move16();
353 2850 : j = 0;
354 2850 : move16();
355 2850 : pPvqVectorBandStart = pPvqVector;
356 115605 : WHILE( LT_16( j, hvq_band_width[k] ) )
357 : {
358 112755 : IF( *pCoefsOut++ == 0 )
359 : {
360 75176 : *pPvqVector++ = *pCoefs; /* Q12 */
361 75176 : move32();
362 75176 : j = add( j, 1 );
363 : }
364 112755 : pCoefs++;
365 : }
366 2850 : logqnorm_ivas_fx( pPvqVectorBandStart, 12, &pvq_norm[k], 40, hvq_band_width[k], &thren_HQ_fx[0] );
367 : }
368 :
369 : /* Normalize coefficients */
370 1467 : normalizecoefs_fx( pvq_vector, pvq_norm, pvq_bands, hvq_band_start, hvq_band_end, pvq_vector_norm );
371 1467 : Q_coefs = 12;
372 1467 : move16();
373 :
374 1467 : bit_budget = sub( bit_budget, i_mult2( HVQ_PVQ_GAIN_BITS, pvq_bands ) );
375 :
376 1467 : pvq_bits = bit_budget;
377 1467 : move16();
378 1467 : set16_fx( npulses, 0, MAX_PVQ_BANDS );
379 :
380 1467 : pvq_encode_frame_ivas_fx( hBstr, pvq_vector_norm, Q_coefs, coefs_pvq, gopt, npulses, pvq_inp_vector, hvq_band_start, hvq_band_end, hvq_band_width, pvq_bands,
381 : Rk, pvq_bits, HQ_CORE );
382 :
383 4317 : FOR( i = 0; i < pvq_bands; i++ )
384 : {
385 2850 : k_sort[i] = i;
386 2850 : move16();
387 : }
388 :
389 :
390 1467 : fine_gain_pred_fx( hvq_band_start, hvq_band_end, hvq_band_width, k_sort, npulses, NULL, NULL, pvq_bands, coefs_pvq,
391 : pvq_inp_vector, fg_pred, HQ_CORE );
392 :
393 1467 : pCoefsOut = &coefs_out[0];
394 1467 : pSelBnds = &sel_bnds[0];
395 1467 : pCoefsPvq = &coefs_pvq[0];
396 4317 : FOR( k = 0; k < pvq_bands; k++ )
397 : {
398 2850 : indx = pvq_norm[k];
399 2850 : move16();
400 2850 : tmp1 = ratio( gopt[k], fg_pred[k], &exp1 );
401 2850 : tmp1 = shr( tmp1, sub( 1, exp1 ) ); /* Q13 */
402 2850 : Mpy_32_16_ss( dicn_fx[indx], tmp1, &normq, &dontCare16 ); /* dicn_fx in Q14, sorted_pvq_gain_pred_err_fx in Q13. */
403 :
404 2850 : logqnorm_fx( &normq, 12, &pvq_norm[k], 40, 1, 0 ); /* normq in Q(14+(16+13)+1-32)=Q12 */
405 2850 : pvq_norm[k] = sub( pvq_norm[k], 8 );
406 2850 : move16();
407 2850 : IF( pvq_norm[k] < 0 )
408 : {
409 0 : pvq_norm[k] = 0;
410 0 : move16();
411 : }
412 :
413 2850 : push_indice( hBstr, IND_HVQ_PVQ_GAIN, pvq_norm[k], HVQ_PVQ_GAIN_BITS );
414 2850 : pvq_bits = add( pvq_bits, HVQ_PVQ_GAIN_BITS );
415 :
416 2850 : pvq_norm[k] = add( pvq_norm[k], 8 );
417 2850 : move16();
418 2850 : indx = pvq_norm[k];
419 2850 : move16();
420 2850 : normq = dicn_fx[indx]; /* in Q14 */
421 2850 : move32();
422 2850 : j = 0;
423 2850 : move16();
424 2850 : IF( GE_16( k, sub( pvq_bands, n_sel_bnds ) ) )
425 : {
426 369 : i = band_start_harm[*pSelBnds++];
427 369 : move16();
428 369 : pCoefsOut = coefs_out + i;
429 : }
430 115605 : WHILE( LT_16( j, hvq_band_width[k] ) )
431 : {
432 112755 : IF( *pCoefsOut == 0 )
433 : {
434 75176 : acc = L_mult( *pCoefsPvq++, fg_pred[k] ); /* in Q(15 + 1 + 12 = 28) */
435 75176 : tmp16 = extract_h( acc ); /* in Q(28 - 16 = 12) */
436 75176 : Mpy_32_16_ss( normq, tmp16, &acc, &dontCare16 ); /* acc(Q11), normq(Q14), tmp16(Q12) */
437 75176 : *pCoefsOut = L_shl( acc, 12 - 11 ); /* Q12 */
438 75176 : move32();
439 75176 : j = add( j, 1 );
440 : }
441 112755 : pCoefsOut++;
442 : }
443 : }
444 1467 : bits = add( bits, pvq_bits );
445 :
446 : /* Noise fill unqantized coeffs with one gain per group */
447 1467 : pCoefsOut = &coefs_out[-1];
448 4401 : FOR( i = 0; i < HVQ_NF_GROUPS; i++ )
449 : {
450 390390 : FOR( j = 0; j < bin_th2; j++ )
451 : {
452 387456 : IF( *( ++pCoefsOut ) == 0 )
453 : {
454 225021 : whiteNoise = Random( &nf_seed ); /* Q15 */
455 225021 : Mpy_32_16_ss( nf_gains[i], whiteNoise, pCoefsOut, &dontCare16 ); /* nf_gains in Q12. *pCoefsOut in Q12 */
456 : }
457 : }
458 : }
459 :
460 1467 : return bits;
461 : }
462 0 : Word16 peak_vq_enc_fx(
463 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
464 : const Word16 bwidth, /* i : audio bandwidth */
465 : const Word32 *coefs, /* i : Input coefficient vector Q12 */
466 : Word32 *coefs_out, /* o : Quantized output vector Q12 */
467 : const Word32 core_brate, /* i : Core bitrate */
468 : const Word16 num_bits, /* i : Number of bits for HVQ */
469 : const Word16 vq_peaks, /* i : Number of identified peaks */
470 : const Word16 *ynrm, /* i : Envelope coefficients */
471 : Word16 *R, /* i/o: Bit allocation/updated bit allocation */
472 : Word16 *vq_peak_idx, /* i : Peak index vector */
473 : Word32 *nf_gains /* i : Estimated noise floor gains Q12 */
474 : )
475 : {
476 : Word16 pos_bits;
477 : Word32 normq;
478 : Word32 pgain_q[HVQ_MAX_PEAKS];
479 : Word32 peak_gains[HVQ_MAX_PEAKS];
480 : Word16 coefs_pvq[HVQ_PVQ_BUF_LEN], *pCoefsPvq; /* Q12 */
481 : Word32 pvq_vector[HVQ_PVQ_BUF_LEN], *pPvqVector;
482 : Word32 *pPvqVectorBandStart;
483 : Word16 pvq_vector_norm[HVQ_PVQ_BUF_LEN];
484 : Word16 fg_pred[NB_SFM_MAX];
485 : Word16 i, j, k, m, r, pvq_bands, num_overlap_bins;
486 : Word16 hcode_l, FlagN, low_peak_bin, vq_cb_idx, max_peaks, bin_th, bin_th2;
487 : Word16 bits;
488 : Word16 nf_seed;
489 : Word16 pgain_cb_idx[HVQ_MAX_PEAKS], pgain_difidx[HVQ_MAX_PEAKS]; /* Q0 */
490 : Word16 pvq_norm[MAX_PVQ_BANDS];
491 : Word16 pvq_bits, bit_budget;
492 : Word16 pos_vec[HVQ_THRES_BIN_32k];
493 : Word16 npulses[MAX_PVQ_BANDS];
494 : Word16 pvq_inp_vector[HVQ_PVQ_BUF_LEN];
495 : Word16 k_sort[MAX_PVQ_BANDS];
496 : Word16 Rk[MAX_PVQ_BANDS];
497 : Word16 gopt[NB_SFM];
498 : Word16 tmp1, exp1;
499 : Word16 Q_coefs;
500 :
501 :
502 : Word16 indx, vqPeaksMinus1, tmp16, whiteNoise;
503 : Word16 *pPgainDifIdx, *pPgainCbIdx, *pVqPeakIdx, *pPosVec;
504 : Word32 *pPeakGains, *pCoefsOut;
505 : const Word32 *pCoefs;
506 : Word32 acc;
507 : UWord16 dontCare16;
508 : Word32 manE_peak, manPeakGains, manPkEnrg; /* Due to very wide dynamic range, use floating point format, i.e., (man, exp) */
509 : Word16 expE_peak, expPeakGains, expPkEnrg;
510 : Word16 *pSelBnds;
511 : Word16 sel_bnds[HVQ_NUM_SFM_24k];
512 : Word16 hvq_band_end[MAX_PVQ_BANDS];
513 : Word16 hvq_band_start[MAX_PVQ_BANDS];
514 : Word16 hvq_band_width[MAX_PVQ_BANDS];
515 : Word16 n_sel_bnds;
516 : UWord32 lsb;
517 :
518 0 : assert( ( core_brate > HQ_16k40 && core_brate <= HQ_48k ) && "HVQ rate not supported" );
519 :
520 : // PMT("max_peaks equation needs to be converted")
521 0 : max_peaks = (Word16) ( ( core_brate * HVQ_PEAKS_PER_DELTA + HVQ_PEAKS_PER_DELTA_OFFS ) / HVQ_PEAKS_BPS_DELTA );
522 :
523 :
524 0 : bits = 0;
525 0 : move16();
526 0 : nf_seed = RANDOM_INITSEED;
527 0 : move16();
528 :
529 :
530 0 : set16_fx( coefs_pvq, 0, HVQ_PVQ_BUF_LEN );
531 0 : set32_fx( pvq_vector, 0, HVQ_PVQ_BUF_LEN );
532 0 : set16_fx( pvq_vector_norm, 0, HVQ_PVQ_BUF_LEN );
533 0 : set16_fx( npulses, 0, MAX_PVQ_BANDS );
534 :
535 0 : bin_th = HVQ_THRES_BIN_32k;
536 0 : move16();
537 0 : bin_th2 = HVQ_THRES_BIN_32k / HVQ_NF_GROUPS;
538 0 : move16();
539 : /* Set bit-rate dependent variables */
540 0 : IF( LT_32( core_brate, HQ_BWE_CROSSOVER_BRATE ) )
541 : {
542 0 : bin_th = HVQ_THRES_BIN_24k;
543 0 : move16();
544 0 : bin_th2 = HVQ_THRES_BIN_24k / HVQ_NF_GROUPS;
545 0 : move16();
546 : }
547 :
548 0 : FOR( i = 0; i < bin_th; i++ )
549 : {
550 0 : pos_vec[i] = 0;
551 0 : move16();
552 : }
553 :
554 : /* Quantize noise floor gains */
555 0 : FOR( i = 0; i < HVQ_NF_GROUPS; i++ )
556 : {
557 0 : logqnorm_fx( &nf_gains[i], 12, &indx, 32, 1, 0 );
558 :
559 : /* De-quantization */
560 0 : acc = dicn_fx[indx]; /* Q14 */
561 0 : move32();
562 0 : nf_gains[i] = L_shr( acc, 1 + 2 ); /* nf_gains in Q12. dicn_fx is in Q14. Need extra shift +2. */
563 0 : move32();
564 0 : push_indice( hBstr, IND_HVQ_NF_GAIN, indx, 5 );
565 0 : bits = add( bits, 5 );
566 : }
567 :
568 : /* Signal number of peaks */
569 0 : i = sub( max_peaks, vq_peaks );
570 0 : push_indice( hBstr, IND_NUM_PEAKS, i, 5 );
571 0 : bits = add( bits, 5 );
572 :
573 : /* Identify position of first peak and arrange peak gains by position */
574 0 : pVqPeakIdx = &vq_peak_idx[0];
575 0 : low_peak_bin = bin_th;
576 0 : FOR( i = 0; i < vq_peaks; i++ )
577 : {
578 0 : indx = *pVqPeakIdx++;
579 0 : move16();
580 0 : IF( LT_16( indx, low_peak_bin ) )
581 : {
582 0 : low_peak_bin = indx;
583 0 : move16();
584 : }
585 : /* Store the sign information. */
586 0 : IF( coefs[indx] < 0 )
587 : {
588 0 : pos_vec[indx] = -1; /* Negative. */
589 0 : move16();
590 : }
591 : ELSE
592 : {
593 0 : pos_vec[indx] = 1; /* Positive */
594 0 : move16();
595 : }
596 : }
597 :
598 0 : pPeakGains = &peak_gains[0];
599 0 : pVqPeakIdx = &vq_peak_idx[0];
600 0 : pPosVec = &pos_vec[0];
601 0 : pCoefs = &coefs[0];
602 0 : FOR( i = 0; i < bin_th; i++ )
603 : {
604 0 : acc = *pCoefs++;
605 0 : IF( *pPosVec++ != 0 )
606 : {
607 0 : *pPeakGains++ = L_abs( acc ); /* in Q12 */
608 0 : move32();
609 0 : *pVqPeakIdx++ = i;
610 0 : move16();
611 : }
612 : }
613 :
614 : /* Scale down peak gains */
615 : /* Divided by 4 is equivalent to consider peak_gains to be in Q14 from Q12.
616 : * No physical bit shift is actually required.
617 : */
618 :
619 : /* Quantize peak gains */
620 0 : pPeakGains = &peak_gains[0];
621 0 : pPgainCbIdx = &pgain_cb_idx[0];
622 0 : logqnorm_fx( pPeakGains++, 14, pPgainCbIdx++, 32, 1, 1 );
623 0 : vqPeaksMinus1 = sub( vq_peaks, 1 );
624 0 : FOR( i = 0; i < vqPeaksMinus1; i++ )
625 : {
626 0 : logqnorm_fx( pPeakGains++, 14, pPgainCbIdx++, 45, 1, 1 );
627 : }
628 :
629 : /* Code quantized peak gain indices
630 : * and also scale up peak gains. */
631 0 : diffcod_fx( vq_peaks, pgain_cb_idx, &pgain_difidx[1] );
632 : /* Accumulate peak energy. */
633 0 : manE_peak = L_deposit_l( 0 );
634 0 : expE_peak = 32;
635 0 : move16();
636 0 : FOR( i = 0; i < vq_peaks; i++ )
637 : {
638 0 : indx = pgain_cb_idx[i];
639 0 : move16();
640 : /* Scale up peak gains */
641 0 : pgain_q[i] = L_shl( dicn_pg_fx[indx], 2 ); /* pgain_q in Q12 */
642 0 : move32();
643 : /* Use floating point operation to deal with wide dynamic range.l
644 : * 32-bit mantissa is used here. It should be even more accurate than
645 : * the floating-point reference code with 24-bit mantissa! */
646 0 : expPeakGains = norm_l( pgain_q[i] );
647 0 : manPeakGains = L_shl( pgain_q[i], expPeakGains );
648 0 : Mpy_32_32_ss( manPeakGains, manPeakGains, &manPkEnrg, &lsb ); /* peak_gains square */
649 0 : expPkEnrg = shl( expPeakGains, 1 ); /* Multiply by 2 due to squaring. */
650 : /* True floating value = manPkEng x 2^(32 - 1 - expPkEnrg - 2*12).
651 : * In this context, the 32-bit manPkEng is in Q0.
652 : * 32 is due to Mpy_32_32() only providing the 32 MSBs of the 64 bits product.
653 : * -1 is due fractional mode Multiply. 2*12 is due to square of Q12. */
654 0 : floating_point_add( &manE_peak, &expE_peak, manPkEnrg, expPkEnrg );
655 : }
656 0 : pgain_difidx[0] = pgain_cb_idx[0];
657 0 : move16();
658 :
659 : /* Huffman coding */
660 0 : hcode_l = 0;
661 0 : move16();
662 0 : pPgainDifIdx = &pgain_difidx[1];
663 0 : FOR( i = 0; i < vqPeaksMinus1; i++ )
664 : {
665 0 : indx = *pPgainDifIdx++;
666 0 : move16();
667 0 : hcode_l = add( hcode_l, pgain_huffsizn[indx] );
668 : }
669 :
670 0 : FlagN = HUFCODE;
671 0 : move16();
672 :
673 0 : tmp16 = extract_l( L_mult0( GAINI_BITS, vqPeaksMinus1 ) );
674 0 : IF( GE_16( hcode_l, tmp16 ) )
675 : {
676 0 : hcode_l = tmp16;
677 0 : move16();
678 0 : FlagN = NOHUFCODE;
679 0 : move16();
680 : }
681 :
682 0 : push_indice( hBstr, IND_FLAGN, FlagN, 1 );
683 0 : push_indice( hBstr, IND_PG_IDX, pgain_difidx[0], GAIN0_BITS );
684 :
685 0 : IF( FlagN )
686 : {
687 0 : pPgainDifIdx = &pgain_difidx[1];
688 0 : FOR( i = 0; i < vqPeaksMinus1; i++ )
689 : {
690 0 : j = *pPgainDifIdx++;
691 0 : move16();
692 0 : m = pgain_huffnorm[j];
693 0 : move16();
694 0 : r = pgain_huffsizn[j];
695 0 : move16();
696 :
697 0 : push_indice( hBstr, IND_PG_IDX, m, r );
698 : }
699 : }
700 : ELSE
701 : {
702 0 : pPgainDifIdx = &pgain_difidx[1];
703 0 : FOR( i = 0; i < vqPeaksMinus1; i++ )
704 : {
705 0 : push_indice( hBstr, IND_PG_IDX, ( *pPgainDifIdx++ ), GAINI_BITS );
706 : }
707 : }
708 :
709 : /* Number of bits used for peak gain quantization */
710 0 : bits = add( bits, add( FLAGN_BITS + GAIN0_BITS, hcode_l ) );
711 :
712 : /* Add sign for peak shape normalization */
713 0 : FOR( i = 0; i < vq_peaks; i++ )
714 : {
715 0 : indx = vq_peak_idx[i];
716 0 : move16();
717 0 : peak_gains[i] = pgain_q[i]; /* Q12 */
718 0 : move32();
719 0 : IF( pos_vec[indx] < 0 )
720 : {
721 0 : peak_gains[i] = L_negate( peak_gains[i] ); /* Q12 */
722 0 : move32();
723 : }
724 : }
725 :
726 : /* Quantize peak shapes */
727 0 : FOR( i = 0; i < vqPeaksMinus1; i++ )
728 : {
729 0 : num_overlap_bins = sub( 5, sub( vq_peak_idx[i + 1], vq_peak_idx[i] ) );
730 0 : indx = sub( vq_peak_idx[i], 2 );
731 0 : quant_peaks_fx( hBstr, &coefs[indx], &coefs_out[indx], &peak_gains[i], &vq_cb_idx, num_overlap_bins, core_brate, vq_peaks );
732 0 : push_indice( hBstr, IND_HVQ_PEAKS, vq_cb_idx, 8 );
733 0 : bits = add( bits, 9 );
734 : }
735 :
736 0 : indx = sub( vq_peak_idx[i], 2 );
737 0 : quant_peaks_fx( hBstr, &coefs[indx], &coefs_out[indx], &peak_gains[i], &vq_cb_idx, 0, core_brate, vq_peaks );
738 0 : push_indice( hBstr, IND_HVQ_PEAKS, vq_cb_idx, 8 );
739 0 : bits = add( bits, 9 );
740 :
741 : /* Quantize peak positions and sign with HVQ */
742 0 : pos_bits = hvq_code_pos_fx( hBstr, pos_vec, bin_th, vq_peaks );
743 :
744 0 : bits = add( bits, pos_bits );
745 0 : bit_budget = sub( num_bits, bits );
746 :
747 : /* Calculate number of PVQ bands to code and assign bits */
748 0 : pvq_bands = hvq_pvq_bitalloc_fx( bit_budget, core_brate, bwidth, ynrm, manE_peak, expE_peak, Rk, R, sel_bnds, &n_sel_bnds );
749 :
750 : /* Get band limits for concatenated PVQ target */
751 0 : hvq_concat_bands_fx( pvq_bands, sel_bnds, n_sel_bnds, hvq_band_start, hvq_band_width, hvq_band_end );
752 :
753 : /* Quantize PVQ bands */
754 0 : pCoefsOut = coefs_out;
755 0 : pCoefs = coefs;
756 0 : pPvqVector = pvq_vector;
757 0 : pSelBnds = sel_bnds;
758 0 : m = bin_th;
759 0 : move16();
760 0 : FOR( k = 0; k < pvq_bands; k++ )
761 : {
762 0 : IF( GE_16( k, sub( pvq_bands, n_sel_bnds ) ) )
763 : {
764 0 : i = band_start_harm[*pSelBnds++];
765 0 : move16();
766 0 : pCoefs = coefs + i;
767 0 : pCoefsOut = coefs_out + i;
768 : }
769 0 : k_sort[k] = k;
770 0 : move16();
771 0 : j = 0;
772 0 : move16();
773 0 : pPvqVectorBandStart = pPvqVector;
774 0 : WHILE( LT_16( j, hvq_band_width[k] ) )
775 : {
776 0 : IF( *pCoefsOut++ == 0 )
777 : {
778 0 : *pPvqVector++ = *pCoefs; /* Q12 */
779 0 : move32();
780 0 : j = add( j, 1 );
781 : }
782 0 : pCoefs++;
783 : }
784 0 : logqnorm_fx( pPvqVectorBandStart, 12, &pvq_norm[k], 40, hvq_band_width[k], 0 );
785 : }
786 :
787 : /* Normalize coefficients */
788 0 : normalizecoefs_fx( pvq_vector, pvq_norm, pvq_bands, hvq_band_start, hvq_band_end, pvq_vector_norm );
789 0 : Q_coefs = 12;
790 0 : move16();
791 :
792 0 : bit_budget = sub( bit_budget, i_mult2( HVQ_PVQ_GAIN_BITS, pvq_bands ) );
793 :
794 0 : pvq_bits = bit_budget;
795 0 : move16();
796 0 : set16_fx( npulses, 0, MAX_PVQ_BANDS );
797 :
798 0 : pvq_encode_frame_fx( hBstr, pvq_vector_norm, Q_coefs, coefs_pvq, gopt, npulses, pvq_inp_vector, hvq_band_start, hvq_band_end, hvq_band_width, pvq_bands,
799 : Rk, pvq_bits, HQ_CORE );
800 :
801 0 : FOR( i = 0; i < pvq_bands; i++ )
802 : {
803 0 : k_sort[i] = i;
804 0 : move16();
805 : }
806 :
807 :
808 0 : fine_gain_pred_fx( hvq_band_start, hvq_band_end, hvq_band_width, k_sort, npulses, NULL, NULL, pvq_bands, coefs_pvq,
809 : pvq_inp_vector, fg_pred, HQ_CORE );
810 :
811 0 : pCoefsOut = &coefs_out[0];
812 0 : pSelBnds = &sel_bnds[0];
813 0 : pCoefsPvq = &coefs_pvq[0];
814 0 : FOR( k = 0; k < pvq_bands; k++ )
815 : {
816 0 : indx = pvq_norm[k];
817 0 : move16();
818 0 : tmp1 = ratio( gopt[k], fg_pred[k], &exp1 );
819 0 : tmp1 = shr( tmp1, sub( 1, exp1 ) ); /* Q13 */
820 0 : Mpy_32_16_ss( dicn_fx[indx], tmp1, &normq, &dontCare16 ); /* dicn_fx in Q14, sorted_pvq_gain_pred_err_fx in Q13. */
821 :
822 0 : logqnorm_fx( &normq, 12, &pvq_norm[k], 40, 1, 0 ); /* normq in Q(14+(16+13)+1-32)=Q12 */
823 0 : pvq_norm[k] = sub( pvq_norm[k], 8 );
824 0 : move16();
825 0 : IF( pvq_norm[k] < 0 )
826 : {
827 0 : pvq_norm[k] = 0;
828 0 : move16();
829 : }
830 :
831 0 : push_indice( hBstr, IND_HVQ_PVQ_GAIN, pvq_norm[k], HVQ_PVQ_GAIN_BITS );
832 0 : pvq_bits = add( pvq_bits, HVQ_PVQ_GAIN_BITS );
833 :
834 0 : pvq_norm[k] = add( pvq_norm[k], 8 );
835 0 : move16();
836 0 : indx = pvq_norm[k];
837 0 : move16();
838 0 : normq = L_add( dicn_fx[indx], 0 ); /* in Q14 */
839 0 : j = 0;
840 0 : move16();
841 0 : IF( GE_16( k, sub( pvq_bands, n_sel_bnds ) ) )
842 : {
843 0 : i = band_start_harm[*pSelBnds++];
844 0 : move16();
845 0 : pCoefsOut = coefs_out + i;
846 : }
847 0 : WHILE( LT_16( j, hvq_band_width[k] ) )
848 : {
849 0 : IF( EQ_32( *pCoefsOut, 0 ) )
850 : {
851 0 : acc = L_mult( *pCoefsPvq++, fg_pred[k] ); /* in Q(15 + 1 + 12 = 28) */
852 0 : tmp16 = extract_h( acc ); /* in Q(28 - 16 = 12) */
853 0 : Mpy_32_16_ss( normq, tmp16, &acc, &dontCare16 ); /* acc(Q11), normq(Q14), tmp16(Q12) */
854 0 : *pCoefsOut = L_shl( acc, 12 - 11 ); /* Q12 */
855 0 : move32();
856 0 : j = add( j, 1 );
857 : }
858 0 : pCoefsOut++;
859 : }
860 : }
861 0 : bits = add( bits, pvq_bits );
862 :
863 : /* Noise fill unqantized coeffs with one gain per group */
864 0 : pCoefsOut = &coefs_out[-1];
865 0 : FOR( i = 0; i < HVQ_NF_GROUPS; i++ )
866 : {
867 0 : FOR( j = 0; j < bin_th2; j++ )
868 : {
869 0 : IF( *( ++pCoefsOut ) == 0 )
870 : {
871 0 : whiteNoise = Random( &nf_seed ); /* Q15 */
872 0 : Mpy_32_16_ss( nf_gains[i], whiteNoise, pCoefsOut, &dontCare16 ); /* nf_gains in Q12. *pCoefsOut in Q12 */
873 : }
874 : }
875 : }
876 :
877 0 : return bits;
878 : }
879 :
880 : /*--------------------------------------------------------------------------
881 : * quant_peaks_fx()
882 : *
883 : * Applies VQ on input vector
884 : *--------------------------------------------------------------------------*/
885 25035 : static void quant_peaks_ivas_fx(
886 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
887 : const Word32 *vect_in, /* i : Target vector in Q12 */
888 : Word32 *vect_out, /* i/o: Quantized vector in Q12 */
889 : const Word32 *peak_gain, /* i : Peak gain vector in Q12 */
890 : Word16 *vq_idx, /* o : Codebook index */
891 : const Word16 overlap, /* i : Overlap indicator */
892 : const Word32 core_brate, /* i : Core bitrate */
893 : const Word16 Npeaks /* i : Number of peaks */
894 : )
895 : {
896 : Word16 x[4]; /* Qx */
897 : Word16 xq[4]; /* Q15 */
898 : Word16 weights[4]; /* Q0 */
899 : Word16 *pWeights;
900 : Word16 i, cb_class, search_overlap, indx, cbSize;
901 : Word16 expPeakGain, manPeakGain, expIn, manIn;
902 : Word32 vectIn, absPeakGain1, absPeakGain;
903 : UWord16 dontCare;
904 : Word16 Qx_vec[4];
905 25035 : Word16 Qx = 15;
906 25035 : move16();
907 25035 : set16_fx( weights, 1, 4 );
908 :
909 : /* Divide vect_in[] by peak_gain to yield x[]. */
910 25035 : expPeakGain = norm_l( *peak_gain ); /* exponent */
911 25035 : manPeakGain = extract_h( L_shl( *peak_gain, expPeakGain ) ); /* mantissa */
912 25035 : manPeakGain = abs_s( manPeakGain ); /* Prepare for div_s() only accepting +ve. */
913 125175 : FOR( i = 0; i < 4; i++ )
914 : {
915 100140 : indx = hvq_index_mapping_fx[i];
916 100140 : move16();
917 100140 : vectIn = L_add( vect_in[indx], 0 );
918 100140 : expIn = norm_l( vectIn ); /* exponent */
919 100140 : expIn = sub( expIn, 1 );
920 100140 : expIn = s_min( expIn, expPeakGain ); /* highest Q is Q15 */
921 100140 : manIn = extract_h( L_shl( vectIn, expIn ) ); /* mantissa */
922 100140 : manIn = abs_s( manIn ); /* Prepare for div_s() only accepting +ve. */
923 :
924 100140 : x[i] = div_s( manIn, manPeakGain ); /* in Q(15+expIn-expPeakGain) */
925 100140 : move16();
926 100140 : Qx_vec[i] = add( 15, sub( expIn, expPeakGain ) );
927 100140 : move16();
928 100140 : Qx = s_min( Qx, Qx_vec[i] );
929 :
930 : /* Restore the sign destroyed by abs operations. */
931 100140 : IF( L_xor( vectIn, *peak_gain ) < 0 ) /* Check the sign bits (MSB). */
932 : {
933 42941 : x[i] = negate( x[i] );
934 42941 : move16();
935 : }
936 : }
937 125175 : FOR( i = 0; i < 4; i++ )
938 : {
939 100140 : IF( NE_16( Qx_vec[i], Qx ) )
940 : {
941 23857 : x[i] = shr( x[i], sub( Qx_vec[i], Qx ) ); /* Qx */
942 23857 : move16();
943 : }
944 : }
945 25035 : absPeakGain = L_abs( peak_gain[0] );
946 25035 : IF( vect_out[0] != 0 )
947 : {
948 2296 : absPeakGain1 = L_abs( peak_gain[-1] );
949 2296 : IF( GT_32( absPeakGain1, absPeakGain ) )
950 : {
951 1663 : weights[0] = 0;
952 1663 : move16();
953 1663 : if ( vect_out[1] != 0 )
954 : {
955 967 : weights[1] = 0;
956 967 : move16();
957 : }
958 : }
959 : }
960 25035 : IF( overlap > 0 )
961 : {
962 4407 : absPeakGain1 = L_abs( peak_gain[1] );
963 4407 : IF( GT_32( absPeakGain1, absPeakGain ) )
964 : {
965 2111 : indx = sub( 4, overlap );
966 2111 : pWeights = &weights[indx];
967 5735 : FOR( i = 0; i < overlap; i++ )
968 : {
969 3624 : *pWeights++ = 0;
970 3624 : move16();
971 : }
972 : }
973 : }
974 :
975 : /* Classify */
976 25035 : cb_class = w_vquant_fx( x, Qx, weights, 0, hvq_class_c_fx, HVQ_NUM_CLASS, 0 );
977 25035 : IF( LT_32( core_brate, HQ_BWE_CROSSOVER_BRATE ) )
978 : {
979 12406 : indx = s_max( 0, sub( HVQ_MAX_PEAKS_24k, Npeaks ) );
980 12406 : search_overlap = hvq_cb_search_overlap24k[indx];
981 12406 : move16();
982 : }
983 : ELSE
984 : {
985 12629 : indx = s_max( 0, sub( HVQ_MAX_PEAKS_32k, Npeaks ) );
986 12629 : search_overlap = hvq_cb_search_overlap32k[indx];
987 12629 : move16();
988 : }
989 :
990 : /* Quantize */
991 25035 : cbSize = add( HVQ_CB_SIZE / 2, search_overlap );
992 25035 : IF( cb_class == 0 )
993 : {
994 6899 : *vq_idx = w_vquant_fx( x, Qx, weights, xq, hvq_peak_cb_fx, cbSize, 0 );
995 6899 : move16();
996 6899 : push_indice( hBstr, IND_HVQ_PEAKS, 0, 1 );
997 : }
998 18136 : ELSE IF( EQ_16( cb_class, 1 ) )
999 : {
1000 5855 : indx = sub( HVQ_CB_SIZE * 2, shl( search_overlap, 2 ) );
1001 5855 : *vq_idx = w_vquant_fx( x, Qx, weights, xq, &hvq_peak_cb_fx[indx], cbSize, 0 );
1002 5855 : move16();
1003 5855 : *vq_idx = add( *vq_idx, sub( HVQ_CB_SIZE / 2, search_overlap ) );
1004 5855 : move16();
1005 5855 : push_indice( hBstr, IND_HVQ_PEAKS, 0, 1 );
1006 : }
1007 12281 : ELSE IF( EQ_16( cb_class, 2 ) )
1008 : {
1009 5742 : indx = sub( HVQ_CB_SIZE * 2, shl( search_overlap, 2 ) );
1010 5742 : *vq_idx = w_vquant_fx( x, Qx, weights, xq, &hvq_peak_cb_fx[indx], cbSize, 1 );
1011 5742 : move16();
1012 5742 : *vq_idx = add( *vq_idx, sub( HVQ_CB_SIZE / 2, search_overlap ) );
1013 5742 : move16();
1014 5742 : push_indice( hBstr, IND_HVQ_PEAKS, 1, 1 );
1015 : }
1016 : ELSE
1017 : {
1018 6539 : *vq_idx = w_vquant_fx( x, Qx, weights, xq, hvq_peak_cb_fx, cbSize, 1 );
1019 6539 : move16();
1020 6539 : push_indice( hBstr, IND_HVQ_PEAKS, 1, 1 );
1021 : }
1022 :
1023 125175 : FOR( i = 0; i < 4; i++ )
1024 : {
1025 100140 : indx = hvq_index_mapping_fx[i];
1026 100140 : move16();
1027 100140 : IF( weights[i] != 0 )
1028 : {
1029 93886 : Mpy_32_16_ss( *peak_gain, xq[i], &vect_out[indx], &dontCare ); /* peak_gains in Q12, xq in Q15 -> Q12. */
1030 93886 : move32();
1031 : }
1032 : }
1033 25035 : vect_out[2] = *peak_gain;
1034 25035 : move32(); /* vect_out in Q12 */
1035 :
1036 25035 : return;
1037 : }
1038 :
1039 0 : static void quant_peaks_fx(
1040 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
1041 : const Word32 *vect_in, /* i : Target vector in Q12 */
1042 : Word32 *vect_out, /* i/o: Quantized vector in Q12 */
1043 : const Word32 *peak_gain, /* i : Peak gain vector in Q12 */
1044 : Word16 *vq_idx, /* o : Codebook index */
1045 : const Word16 overlap, /* i : Overlap indicator */
1046 : const Word32 core_brate, /* i : Core bitrate */
1047 : const Word16 Npeaks /* i : Number of peaks */
1048 : )
1049 : {
1050 : Word16 x[4]; /* Qx */
1051 : Word16 xq[4]; /* Q15 */
1052 : Word16 weights[4]; /* Q0 */
1053 : Word16 *pWeights;
1054 : Word16 i, cb_class, search_overlap, indx, cbSize;
1055 : Word16 expPeakGain, manPeakGain, expIn, manIn;
1056 : Word32 vectIn, absPeakGain1, absPeakGain;
1057 : UWord16 dontCare;
1058 : Word16 Qx_vec[4];
1059 0 : Word16 Qx = 15;
1060 :
1061 0 : set16_fx( weights, 1, 4 );
1062 :
1063 : /* Divide vect_in[] by peak_gain to yield x[]. */
1064 0 : expPeakGain = norm_l( *peak_gain ); /* exponent */
1065 0 : manPeakGain = extract_h( L_shl( *peak_gain, expPeakGain ) ); /* mantissa */
1066 0 : manPeakGain = abs_s( manPeakGain ); /* Prepare for div_s() only accepting +ve. */
1067 0 : FOR( i = 0; i < 4; i++ )
1068 : {
1069 0 : indx = hvq_index_mapping_fx[i];
1070 0 : move16();
1071 0 : vectIn = L_add( vect_in[indx], 0 );
1072 0 : expIn = norm_l( vectIn ); /* exponent */
1073 0 : expIn = sub( expIn, 1 );
1074 0 : expIn = s_min( expIn, expPeakGain ); /* highest Q is Q15 */
1075 0 : manIn = extract_h( L_shl( vectIn, expIn ) ); /* mantissa */
1076 0 : manIn = abs_s( manIn ); /* Prepare for div_s() only accepting +ve. */
1077 :
1078 0 : x[i] = div_s( manIn, manPeakGain ); /* in Q(15+expIn-expPeakGain) */
1079 :
1080 0 : Qx_vec[i] = add( 15, sub( expIn, expPeakGain ) );
1081 0 : move16();
1082 0 : Qx = s_min( Qx, Qx_vec[i] );
1083 :
1084 : /* Restore the sign destroyed by abs operations. */
1085 0 : if ( L_xor( vectIn, *peak_gain ) < 0 ) /* Check the sign bits (MSB). */
1086 : {
1087 0 : x[i] = negate( x[i] );
1088 0 : move16();
1089 : }
1090 : }
1091 0 : FOR( i = 0; i < 4; i++ )
1092 : {
1093 0 : IF( NE_16( Qx_vec[i], Qx ) )
1094 : {
1095 0 : x[i] = shr( x[i], sub( Qx_vec[i], Qx ) ); /* Qx */
1096 0 : move16();
1097 : }
1098 : }
1099 0 : absPeakGain = L_abs( peak_gain[0] );
1100 0 : IF( vect_out[0] != 0 )
1101 : {
1102 0 : absPeakGain1 = L_abs( peak_gain[-1] );
1103 0 : IF( GT_32( absPeakGain1, absPeakGain ) )
1104 : {
1105 0 : weights[0] = 0;
1106 0 : move16();
1107 0 : if ( vect_out[1] != 0 )
1108 : {
1109 0 : weights[1] = 0;
1110 0 : move16();
1111 : }
1112 : }
1113 : }
1114 0 : IF( overlap > 0 )
1115 : {
1116 0 : absPeakGain1 = L_abs( peak_gain[1] );
1117 0 : IF( GT_32( absPeakGain1, absPeakGain ) )
1118 : {
1119 0 : indx = sub( 4, overlap );
1120 0 : pWeights = &weights[indx];
1121 0 : FOR( i = 0; i < overlap; i++ )
1122 : {
1123 0 : *pWeights++ = 0;
1124 0 : move16();
1125 : }
1126 : }
1127 : }
1128 :
1129 : /* Classify */
1130 : #if HVQ_VQ_DIM != 5
1131 : #error w_vquant_fx() is hard-wired to dim = 4 = (HVQ_VQ_DIM - 1).
1132 : #endif
1133 0 : cb_class = w_vquant_fx( x, Qx, weights, 0, hvq_class_c_fx, HVQ_NUM_CLASS, 0 );
1134 0 : IF( LT_32( core_brate, HQ_BWE_CROSSOVER_BRATE ) )
1135 : {
1136 0 : indx = sub( HVQ_MAX_PEAKS_24k, Npeaks );
1137 0 : search_overlap = hvq_cb_search_overlap24k[indx];
1138 0 : move16();
1139 : }
1140 : ELSE
1141 : {
1142 0 : indx = sub( HVQ_MAX_PEAKS_32k, Npeaks );
1143 0 : search_overlap = hvq_cb_search_overlap32k[indx];
1144 0 : move16();
1145 : }
1146 :
1147 : /* Quantize */
1148 0 : cbSize = add( HVQ_CB_SIZE / 2, search_overlap );
1149 0 : IF( cb_class == 0 )
1150 : {
1151 0 : *vq_idx = w_vquant_fx( x, Qx, weights, xq, hvq_peak_cb_fx, cbSize, 0 );
1152 0 : move16();
1153 0 : push_indice( hBstr, IND_HVQ_PEAKS, 0, 1 );
1154 : }
1155 0 : ELSE IF( EQ_16( cb_class, 1 ) )
1156 : {
1157 0 : indx = sub( HVQ_CB_SIZE * 2, shl( search_overlap, 2 ) );
1158 0 : *vq_idx = w_vquant_fx( x, Qx, weights, xq, &hvq_peak_cb_fx[indx], cbSize, 0 );
1159 0 : move16();
1160 0 : *vq_idx = add( *vq_idx, sub( HVQ_CB_SIZE / 2, search_overlap ) );
1161 0 : move16();
1162 0 : push_indice( hBstr, IND_HVQ_PEAKS, 0, 1 );
1163 : }
1164 0 : ELSE IF( EQ_16( cb_class, 2 ) )
1165 : {
1166 0 : indx = sub( HVQ_CB_SIZE * 2, shl( search_overlap, 2 ) );
1167 0 : *vq_idx = w_vquant_fx( x, Qx, weights, xq, &hvq_peak_cb_fx[indx], cbSize, 1 );
1168 0 : move16();
1169 0 : *vq_idx = add( *vq_idx, sub( HVQ_CB_SIZE / 2, search_overlap ) );
1170 0 : move16();
1171 0 : push_indice( hBstr, IND_HVQ_PEAKS, 1, 1 );
1172 : }
1173 : ELSE
1174 : {
1175 0 : *vq_idx = w_vquant_fx( x, Qx, weights, xq, hvq_peak_cb_fx, cbSize, 1 );
1176 0 : move16();
1177 0 : push_indice( hBstr, IND_HVQ_PEAKS, 1, 1 );
1178 : }
1179 :
1180 0 : FOR( i = 0; i < 4; i++ )
1181 : {
1182 0 : indx = hvq_index_mapping_fx[i];
1183 0 : move16();
1184 0 : IF( weights[i] != 0 )
1185 : {
1186 0 : Mpy_32_16_ss( *peak_gain, xq[i], &vect_out[indx], &dontCare ); /* peak_gains in Q12, xq in Q15 -> Q12. */
1187 0 : move32();
1188 : }
1189 : }
1190 0 : vect_out[2] = *peak_gain;
1191 0 : move32(); /* vect_out in Q12 */
1192 :
1193 0 : return;
1194 : }
1195 :
1196 : /*--------------------------------------------------------------------------
1197 : * code_pos()
1198 : *
1199 : * Code pulse positions
1200 : *--------------------------------------------------------------------------*/
1201 :
1202 1467 : static Word16 sparse_code_pos_fx(
1203 : const Word16 *inp,
1204 : const Word16 length,
1205 : Word16 *result )
1206 : {
1207 : Word16 layer2[HVQ_CP_L2_MAX];
1208 : Word16 layer_length;
1209 : Word16 i, j, tmp;
1210 : Word16 val, idx;
1211 1467 : Word16 bits = 0;
1212 : Word16 mask;
1213 :
1214 1467 : set16_fx( layer2, 0, HVQ_CP_L2_MAX );
1215 :
1216 : /*layer_length = (short)((float)length/HVQ_CP_L1_LEN + 0.5); */
1217 1467 : layer_length = round_fx( L_mult0( length, 13107 ) ); /* 0+16-16, 13107 is 1/5 in Q16 */
1218 :
1219 79129 : FOR( j = 0; j < layer_length; j++ )
1220 : {
1221 77662 : tmp = s_min( i_mult2( add( j, 1 ), HVQ_CP_L1_LEN ), length );
1222 393220 : FOR( i = i_mult2( j, HVQ_CP_L1_LEN ); i < tmp; i++ )
1223 : {
1224 339302 : IF( inp[i] != 0 )
1225 : {
1226 23744 : layer2[j] = 1;
1227 23744 : move16();
1228 23744 : BREAK;
1229 : }
1230 : }
1231 : }
1232 :
1233 79129 : FOR( i = 0; i < layer_length; i++ )
1234 : {
1235 77662 : result[i] = layer2[i];
1236 77662 : move16();
1237 : }
1238 1467 : bits = add( bits, layer_length );
1239 :
1240 79129 : FOR( j = 0; j < layer_length; j++ )
1241 : {
1242 77662 : IF( layer2[j] != 0 )
1243 : {
1244 23744 : val = 0;
1245 23744 : move16();
1246 23744 : tmp = s_min( i_mult2( add( j, 1 ), HVQ_CP_L1_LEN ), length );
1247 142446 : FOR( i = i_mult2( j, HVQ_CP_L1_LEN ); i < tmp; i++ )
1248 : {
1249 118702 : val = shl( val, 1 );
1250 118702 : val = s_or( val, inp[i] );
1251 : }
1252 :
1253 77614 : FOR( idx = 0; idx < HVQ_CP_MAP_LEN; idx++ )
1254 : {
1255 77614 : IF( EQ_16( hvq_cp_layer1_map5[idx], val ) )
1256 : {
1257 23744 : BREAK;
1258 : }
1259 : }
1260 :
1261 23744 : mask = shl( 1, HVQ_CP_MAP_IDX_LEN - 1 );
1262 94976 : FOR( i = 0; i < HVQ_CP_MAP_IDX_LEN; i++ )
1263 : {
1264 71232 : result[bits++] = shr( s_and( idx, mask ), sub( HVQ_CP_MAP_IDX_LEN - 1, i ) );
1265 71232 : mask = shr( mask, 1 );
1266 : }
1267 : }
1268 : }
1269 :
1270 1467 : return bits;
1271 : }
1272 :
1273 : /*--------------------------------------------------------------------------
1274 : * hvq_code_pos()
1275 : *
1276 : * Code pulse positions
1277 : *--------------------------------------------------------------------------*/
1278 1467 : static Word16 hvq_code_pos_ivas_fx(
1279 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
1280 : const Word16 *inp,
1281 : const Word16 length,
1282 : const Word16 num_peaks )
1283 : {
1284 : Word16 sparse_result[4 * HVQ_THRES_BIN_32k / HVQ_CP_L1_LEN];
1285 : Word16 delta[HVQ_MAX_PEAKS];
1286 : Word16 peak_idx[HVQ_MAX_PEAKS];
1287 : Word16 inp_abs[HVQ_THRES_BIN_32k];
1288 : Word16 inp_sign[HVQ_MAX_PEAKS];
1289 :
1290 : Word16 i, j;
1291 : Word16 bits;
1292 : Word16 delta_max;
1293 : Word16 delta_bits, sparse_bits;
1294 : Word16 tmp;
1295 :
1296 1467 : bits = 0;
1297 1467 : move16();
1298 :
1299 : /* Extract sorted peak index vector and sign vector */
1300 1467 : j = 0;
1301 1467 : move16();
1302 388923 : FOR( i = 0; i < length; i++ )
1303 : {
1304 387456 : inp_abs[i] = abs_s( inp[i] );
1305 387456 : move16();
1306 387456 : IF( inp[i] != 0 )
1307 : {
1308 25035 : peak_idx[j] = i;
1309 25035 : move16();
1310 25035 : inp_sign[j] = inp[i];
1311 25035 : move16();
1312 25035 : j = add( j, 1 );
1313 : }
1314 : }
1315 :
1316 : /* Calculate delta */
1317 1467 : delta[0] = add( peak_idx[0], HVQ_CP_HUFF_OFFSET );
1318 1467 : move16();
1319 1467 : delta_max = delta[0];
1320 1467 : move16();
1321 25035 : FOR( i = 1; i < num_peaks; i++ )
1322 : {
1323 23568 : delta[i] = sub( sub( peak_idx[i], peak_idx[i - 1] ), HVQ_CP_HUFF_OFFSET );
1324 23568 : move16();
1325 23568 : if ( LT_16( delta_max, delta[i] ) )
1326 : {
1327 3193 : delta_max = delta[i];
1328 3193 : move16();
1329 : }
1330 : }
1331 :
1332 : /* Calculate bits needed for huffman coding of deltas */
1333 1467 : delta_bits = -1;
1334 1467 : move16();
1335 1467 : IF( LE_16( delta_max, HVQ_CP_HUFF_MAX ) )
1336 : {
1337 1420 : delta_bits = 0;
1338 1420 : move16();
1339 25852 : FOR( i = 0; i < num_peaks; i++ )
1340 : {
1341 24432 : delta_bits = add( delta_bits, hvq_cp_huff_len[delta[i]] );
1342 : }
1343 : }
1344 :
1345 : /* Calculate bits neeed for sparse coding */
1346 1467 : sparse_bits = sparse_code_pos_fx( inp_abs, length, sparse_result );
1347 :
1348 : /* Decide which coding mode to use */
1349 1467 : test();
1350 1467 : IF( GT_16( delta_bits, sparse_bits ) || delta_bits < 0 )
1351 : {
1352 167 : push_indice( hBstr, IND_POS_IDX, HVQ_CP_SPARSE, 1 );
1353 :
1354 15206 : FOR( i = 0; i < sparse_bits; i++ )
1355 : {
1356 15039 : push_indice( hBstr, IND_POS_IDX, sparse_result[i], 1 );
1357 : }
1358 167 : bits = add( add( bits, sparse_bits ), 1 );
1359 : }
1360 : ELSE
1361 : {
1362 1300 : push_indice( hBstr, IND_POS_IDX, HVQ_CP_DELTA, 1 );
1363 :
1364 23771 : FOR( i = 0; i < num_peaks; i++ )
1365 : {
1366 22471 : j = delta[i];
1367 22471 : move16();
1368 22471 : push_indice( hBstr, IND_POS_IDX, hvq_cp_huff_val[j], hvq_cp_huff_len[j] );
1369 : }
1370 1300 : bits = add( add( bits, delta_bits ), 1 );
1371 : }
1372 :
1373 : /* Send sign */
1374 26502 : FOR( i = 0; i < num_peaks; i++ )
1375 : {
1376 25035 : tmp = 1;
1377 25035 : move16();
1378 25035 : if ( inp_sign[i] < 0 )
1379 : {
1380 12700 : tmp = 0;
1381 12700 : move16();
1382 : }
1383 25035 : push_indice( hBstr, IND_POS_IDX, tmp, 1 );
1384 : }
1385 1467 : bits = add( bits, num_peaks );
1386 :
1387 1467 : return bits;
1388 : }
1389 :
1390 0 : static Word16 hvq_code_pos_fx(
1391 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
1392 : const Word16 *inp,
1393 : const Word16 length,
1394 : const Word16 num_peaks )
1395 : {
1396 : Word16 sparse_result[4 * HVQ_THRES_BIN_32k / HVQ_CP_L1_LEN];
1397 : Word16 delta[HVQ_MAX_PEAKS];
1398 : Word16 peak_idx[HVQ_MAX_PEAKS];
1399 : Word16 inp_abs[HVQ_THRES_BIN_32k];
1400 : Word16 inp_sign[HVQ_MAX_PEAKS];
1401 :
1402 : Word16 i, j;
1403 : Word16 bits;
1404 : Word16 delta_max;
1405 : Word16 delta_bits, sparse_bits;
1406 : Word16 tmp;
1407 :
1408 0 : bits = 0;
1409 0 : move16();
1410 :
1411 : /* Extract sorted peak index vector and sign vector */
1412 0 : j = 0;
1413 0 : move16();
1414 0 : FOR( i = 0; i < length; i++ )
1415 : {
1416 0 : inp_abs[i] = abs_s( inp[i] );
1417 0 : IF( inp[i] != 0 )
1418 : {
1419 0 : peak_idx[j] = i;
1420 0 : move16();
1421 0 : inp_sign[j] = inp[i];
1422 0 : move16();
1423 0 : j = add( j, 1 );
1424 : }
1425 : }
1426 :
1427 : /* Calculate delta */
1428 0 : delta[0] = add( peak_idx[0], HVQ_CP_HUFF_OFFSET );
1429 0 : move16();
1430 0 : delta_max = delta[0];
1431 0 : move16();
1432 0 : FOR( i = 1; i < num_peaks; i++ )
1433 : {
1434 0 : delta[i] = sub( sub( peak_idx[i], peak_idx[i - 1] ), HVQ_CP_HUFF_OFFSET );
1435 0 : move16();
1436 0 : if ( LT_16( delta_max, delta[i] ) )
1437 : {
1438 0 : delta_max = delta[i];
1439 0 : move16();
1440 : }
1441 : }
1442 :
1443 : /* Calculate bits needed for huffman coding of deltas */
1444 0 : delta_bits = -1;
1445 0 : move16();
1446 0 : IF( LE_16( delta_max, HVQ_CP_HUFF_MAX ) )
1447 : {
1448 0 : delta_bits = 0;
1449 0 : move16();
1450 0 : FOR( i = 0; i < num_peaks; i++ )
1451 : {
1452 0 : delta_bits = add( delta_bits, hvq_cp_huff_len[delta[i]] );
1453 : }
1454 : }
1455 :
1456 : /* Calculate bits neeed for sparse coding */
1457 0 : sparse_bits = sparse_code_pos_fx( inp_abs, length, sparse_result );
1458 :
1459 : /* Decide which coding mode to use */
1460 0 : test();
1461 0 : IF( GT_16( delta_bits, sparse_bits ) || delta_bits < 0 )
1462 : {
1463 0 : push_indice( hBstr, IND_POS_IDX, HVQ_CP_SPARSE, 1 );
1464 :
1465 0 : FOR( i = 0; i < sparse_bits; i++ )
1466 : {
1467 0 : push_indice( hBstr, IND_POS_IDX, sparse_result[i], 1 );
1468 : }
1469 0 : bits = add( add( bits, sparse_bits ), 1 );
1470 : }
1471 : ELSE
1472 : {
1473 0 : push_indice( hBstr, IND_POS_IDX, HVQ_CP_DELTA, 1 );
1474 :
1475 0 : FOR( i = 0; i < num_peaks; i++ )
1476 : {
1477 0 : j = delta[i];
1478 0 : move16();
1479 0 : push_indice( hBstr, IND_POS_IDX, hvq_cp_huff_val[j], hvq_cp_huff_len[j] );
1480 : }
1481 0 : bits = add( add( bits, delta_bits ), 1 );
1482 : }
1483 :
1484 : /* Send sign */
1485 0 : FOR( i = 0; i < num_peaks; i++ )
1486 : {
1487 0 : tmp = 1;
1488 0 : move16();
1489 0 : if ( inp_sign[i] < 0 )
1490 : {
1491 0 : tmp = 0;
1492 0 : move16();
1493 : }
1494 0 : push_indice( hBstr, IND_POS_IDX, tmp, 1 );
1495 : }
1496 0 : bits = add( bits, num_peaks );
1497 :
1498 0 : return bits;
1499 : }
|