190 lines
6.3 KiB
C++
Executable File
190 lines
6.3 KiB
C++
Executable File
/*====================================================================================
|
|
EVS Codec 3GPP TS26.442 Apr 03, 2018. Version 12.11.0 / 13.6.0 / 14.2.0
|
|
====================================================================================*/
|
|
|
|
#include "options.h" /* Compilation switches */
|
|
#include "stl.h" /* required by wmc_tool */
|
|
|
|
#include "rom_com_fx.h"
|
|
|
|
#include "prot_fx.h" /* Function prototypes */
|
|
#include "cnst_fx.h" /* Common constants */
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
/* Function hvq_pvq_bitalloc */
|
|
/* ~~~~~~~~~~~~~~~~~~~~~~~~ */
|
|
/* */
|
|
/* Calculate the number of PVQ bands to code and allocate bits based on */
|
|
/* the number of available bits. */
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
Word16 hvq_pvq_bitalloc_fx(
|
|
Word16 num_bits, /* i/o: Number of available bits (including gain bits) */
|
|
const Word32 brate, /* i : bitrate */
|
|
const Word16 bwidth_fx, /* i : Encoded bandwidth */
|
|
const Word16 *ynrm, /* i : Envelope coefficients */
|
|
const Word32 manE_peak, /* i : Peak energy mantissa */
|
|
const Word16 expE_peak, /* i : Peak energy exponent */
|
|
Word16 *Rk, /* o : bit allocation for concatenated vector */
|
|
Word16 *R, /* i/o: Global bit allocation */
|
|
Word16 *sel_bands, /* o : Selected bands for encoding */
|
|
Word16 *n_sel_bands /* o : No. of selected bands for encoding */
|
|
)
|
|
{
|
|
Word16 num_bands, band_max_bits;
|
|
Word16 one_over_band_max_bits;
|
|
Word16 k;
|
|
Word16 reciprocal, envSum, expo, align, m, n, indx;
|
|
Word16 k_max;
|
|
Word16 k_start;
|
|
Word32 E_max, E_max5;
|
|
Word32 tmp, acc;
|
|
Word32 env_mean;
|
|
UWord16 lsb;
|
|
Word16 num_sfm;
|
|
|
|
IF (sub(bwidth_fx, FB) == 0)
|
|
{
|
|
num_sfm = SFM_N_HARM_FB;
|
|
}
|
|
ELSE
|
|
{
|
|
num_sfm = SFM_N_HARM;
|
|
}
|
|
|
|
IF ( L_sub(brate, HQ_24k40) == 0 )
|
|
{
|
|
band_max_bits = HVQ_BAND_MAX_BITS_24k;
|
|
move16();
|
|
one_over_band_max_bits = ONE_OVER_HVQ_BAND_MAX_BITS_24k_FX;
|
|
move16();
|
|
k_start = HVQ_THRES_SFM_24k;
|
|
move16();
|
|
IF (sub(bwidth_fx, FB) == 0)
|
|
{
|
|
reciprocal = 2731; /* Q15, 1/(SFM_N_HARM_FB + 1 - k_start) */ move16();
|
|
}
|
|
ELSE
|
|
{
|
|
reciprocal = 3277; /* Q15, 1/(SFM_N_HARM + 1 - k_start) */ move16();
|
|
}
|
|
}
|
|
ELSE
|
|
{
|
|
band_max_bits = HVQ_BAND_MAX_BITS_32k;
|
|
move16();
|
|
one_over_band_max_bits = ONE_OVER_HVQ_BAND_MAX_BITS_32k_FX;
|
|
move16();
|
|
k_start = HVQ_THRES_SFM_32k;
|
|
move16();
|
|
IF (sub(bwidth_fx, FB) == 0)
|
|
{
|
|
reciprocal = 3641; /* Q15, 1/(SFM_N_HARM_FB + 1 - k_start) */ move16();
|
|
}
|
|
ELSE
|
|
{
|
|
reciprocal = 4681; /* Q15, 1/(SFM_N_HARM + 1 - k_start) */ move16();
|
|
}
|
|
}
|
|
|
|
num_bands = mult( num_bits, one_over_band_max_bits ); /* Q0 */
|
|
num_bits = sub( num_bits, i_mult(num_bands, band_max_bits) ); /* Q0 */
|
|
|
|
IF ( sub(num_bits, HVQ_NEW_BAND_BIT_THR) >= 0 )
|
|
{
|
|
num_bands = add(num_bands, 1);
|
|
}
|
|
ELSE
|
|
{
|
|
num_bits = add(num_bits, band_max_bits);
|
|
}
|
|
|
|
/* safety check in case of bit errors */
|
|
if (sub(num_bands, 1) < 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
*n_sel_bands = 0;
|
|
move16();
|
|
envSum = 0;
|
|
move16();
|
|
E_max = L_deposit_l(0);
|
|
k_max = k_start;
|
|
move16();
|
|
FOR ( k = k_start; k < num_sfm; k++ )
|
|
{
|
|
indx = ynrm[k];
|
|
move16();
|
|
tmp = L_add(0,dicn_fx[indx]); /* Q14 */
|
|
envSum = add(envSum, indx); /* Since the size of dicn_fx = 40, ynrm[k] must be less than 41. 16 bits are enough for envSum.*/
|
|
IF (L_sub(tmp, E_max) > 0)
|
|
{
|
|
E_max = L_add(0,tmp);
|
|
k_max = k;
|
|
move16();
|
|
}
|
|
}
|
|
env_mean = L_mult(envSum, reciprocal); /* env_mean in Q16 */
|
|
IF (L_sub(L_sub(env_mean, L_deposit_h(ynrm[k_max])), 0x30000L) > 0) /* condition: env_mean - ynrm[k_max] > 3 */
|
|
{
|
|
expo = norm_l(E_max);
|
|
E_max = L_shl(E_max, expo);
|
|
Mpy_32_16_ss(E_max, 0x7a12, &E_max5, &lsb); /* NB: 5.0e5 = 0x7a12(Q15) x 2^19. */
|
|
/* True floating point value of E_max*5e5 = E_max5 x 2^(19 - expo - 14).
|
|
* In this context, the 32-bit E_max5 is in Q0, and
|
|
* -14 is due to Emax in Q14.
|
|
* True floating point value of E_peak = manE_peak x 2^(31 - expE_peak - 2*12). See peak_vq_enc_fx().
|
|
*/
|
|
|
|
/* Align the Q-points of the floating point Emax*5e5 and E_peak. */
|
|
align = sub(expo, expE_peak);
|
|
align = add(align, (19 - 14) - (31 - 2*12));
|
|
IF (align < 0)
|
|
{
|
|
acc = L_sub(E_max5, L_shl(manE_peak, align));
|
|
}
|
|
ELSE
|
|
{
|
|
acc = L_sub(L_shr(E_max5, align), manE_peak);
|
|
}
|
|
|
|
IF (acc > 0) /* condition: E_max*5.e5 > E_peak */
|
|
{
|
|
IF ( sub(band_len_harm[k_max], 96) == 0 )
|
|
{
|
|
n = 61;
|
|
}
|
|
ELSE
|
|
{
|
|
QuantaPerDsDirac_fx(band_len_harm[k_max], 1, hBitsN, &n);
|
|
}
|
|
m = shl(sub(num_bits, HVQ_PVQ_GAIN_BITS), 3);
|
|
IF (sub(m, n) >= 0)
|
|
{
|
|
IF (sub(num_bands, 1) > 0) /* condition: num_bands > 1 */
|
|
{
|
|
sel_bands[*n_sel_bands] = k_max;
|
|
move16();
|
|
*n_sel_bands = add(*n_sel_bands, 1);
|
|
R[k_max] = 1; /* Mark that the band has been encoded for fill_spectrum */ move16();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Allocate bits */
|
|
tmp = sub(num_bands,1);
|
|
FOR (k = 0; k < tmp; k++)
|
|
{
|
|
Rk[k] = shl(sub(band_max_bits, HVQ_PVQ_GAIN_BITS), 3);
|
|
move16();
|
|
}
|
|
/* NB: When it exits the above loop, k = num_bands - 1. */
|
|
Rk[k] = shl(sub(num_bits, HVQ_PVQ_GAIN_BITS), 3);
|
|
move16();
|
|
|
|
return num_bands;
|
|
}
|
|
|