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