979 lines
27 KiB
C++
979 lines
27 KiB
C++
/*====================================================================================
|
|
EVS Codec 3GPP TS26.443 Nov 13, 2018. Version 12.11.0 / 13.7.0 / 14.3.0 / 15.1.0
|
|
====================================================================================*/
|
|
|
|
#include "options.h"
|
|
#include "cnst.h"
|
|
#include "rom_com.h"
|
|
#include "prot.h"
|
|
#include "basop_util.h"
|
|
#include "basop_proto_func.h"
|
|
|
|
namespace evs {
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* bitalloc()
|
|
*
|
|
* Adaptive bit allocation for 20kHz audio codec
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
void bitalloc (
|
|
short *y, /* i : reordered norm of sub-vectors */
|
|
short *idx, /* i : reordered sub-vector indices */
|
|
short sum, /* i : number of available bits */
|
|
short N, /* i : number of norms */
|
|
short K, /* i : maximum number of bits per dimension */
|
|
short *r, /* o : bit-allacation vector */
|
|
const short *sfmsize, /* i : band length */
|
|
const short hqswb_clas /* i : signal classification flag */
|
|
)
|
|
{
|
|
short i, j, k, n, m, v, im;
|
|
short diff, temp;
|
|
short fac;
|
|
short ii;
|
|
short SFM_thr = SFM_G1G2;
|
|
|
|
N -= 1;
|
|
|
|
if ( hqswb_clas == HQ_HARMONIC )
|
|
{
|
|
SFM_thr = 22;
|
|
}
|
|
|
|
fac = 3;
|
|
K -= 2;
|
|
im = 1;
|
|
diff = sum;
|
|
n = sum >> 3;
|
|
for ( i=0; i<n; i++ )
|
|
{
|
|
k = 0;
|
|
temp = y[0];
|
|
for (m=1; m<im; m++)
|
|
{
|
|
if ( temp < y[m] )
|
|
{
|
|
temp = y[m];
|
|
k = m;
|
|
}
|
|
}
|
|
|
|
if ( temp < y[m] )
|
|
{
|
|
k = m;
|
|
if ( im < N)
|
|
{
|
|
im++;
|
|
}
|
|
}
|
|
|
|
j = idx[k];
|
|
if ( sum >= sfmsize[j] && r[j] < K )
|
|
{
|
|
y[k] -= fac;
|
|
r[j]++;
|
|
if ( r[j] >= K )
|
|
{
|
|
y[k] = MIN16B;
|
|
}
|
|
sum -= sfmsize[j];
|
|
}
|
|
else
|
|
{
|
|
y[k] = MIN16B;
|
|
k++;
|
|
if ( k == im && im < N )
|
|
{
|
|
im++;
|
|
}
|
|
}
|
|
|
|
if ( sum < WID_G1 || diff == sum )
|
|
{
|
|
break;
|
|
}
|
|
|
|
diff = sum;
|
|
v = N - 1;
|
|
|
|
if (k > v)
|
|
{
|
|
for ( ii=0; ii<=N; ii++ )
|
|
{
|
|
if ( y[ii] > MIN16B )
|
|
{
|
|
if( ii < N )
|
|
{
|
|
im = ii + 1;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( sum >= WID_G2)
|
|
{
|
|
for (i=0; i<=N; i++)
|
|
{
|
|
j = idx[i];
|
|
if ( j >= SFM_G1 && j < SFM_thr && r[j] == 0 )
|
|
{
|
|
r[j] = 1;
|
|
sum -= WID_G2;
|
|
if ( sum < WID_G2 )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( sum >= WID_G2 )
|
|
{
|
|
for (i=0; i<=N; i++)
|
|
{
|
|
j = idx[i];
|
|
if ( j >= SFM_G1 && j < SFM_thr && r[j] == 1 )
|
|
{
|
|
r[j] = 2;
|
|
sum -= WID_G2;
|
|
if ( sum < WID_G2 )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( sum >= WID_G1 )
|
|
{
|
|
for (i=0; i<=N; i++)
|
|
{
|
|
j = idx[i];
|
|
if ( j < SFM_G1 && r[j] == 0 )
|
|
{
|
|
r[j] = 1;
|
|
sum -= WID_G1;
|
|
if ( sum < WID_G1 )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( sum >= WID_G1 )
|
|
{
|
|
for (i=0; i<=N; i++)
|
|
{
|
|
j = idx[i];
|
|
if ( j < SFM_G1 && r[j] == 1 )
|
|
{
|
|
r[j] = 2;
|
|
sum -= WID_G1;
|
|
if ( sum < WID_G1 )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------*
|
|
* BitAllocF()
|
|
*
|
|
* Fractional bit allocation
|
|
*-------------------------------------------------------------------*/
|
|
|
|
short BitAllocF (
|
|
short *y, /* i : norm of sub-vectors */
|
|
long bit_rate, /* i : bitrate */
|
|
short B, /* i : number of available bits */
|
|
short N, /* i : number of sub-vectors */
|
|
short *R, /* o : bit-allocation indicator */
|
|
short *Rsubband, /* o : sub-band bit-allocation vector (Q3) */
|
|
const short hqswb_clas, /* i : hq swb class */
|
|
const short num_env_bands /* i : Number sub bands to be encoded for HQ_SWB_BWE */
|
|
)
|
|
{
|
|
Word16 fac;
|
|
Word16 i, n, Nmin, Bits, bs, low_rate = 0;
|
|
|
|
Word16 m_fx;
|
|
Word32 t_fx, B_fx;
|
|
Word32 L_tmp1, L_tmp2;
|
|
Word16 tmp, exp1, exp2;
|
|
Word32 Rsubband_w32_fx[NB_SFM]; /* Q15 */
|
|
Word16 B_w16_fx;
|
|
|
|
set_i( Rsubband_w32_fx, 0, NB_SFM);
|
|
|
|
fac = 3;
|
|
if (L_sub(bit_rate, 32000) < 0)
|
|
{
|
|
bs = 2;
|
|
}
|
|
else
|
|
{
|
|
bs = 3;
|
|
}
|
|
low_rate = 1;
|
|
|
|
Nmin = N;
|
|
if ( sub(Nmin,SFM_N) > 0)
|
|
{
|
|
Nmin = SFM_N;
|
|
}
|
|
|
|
/* Initial bits distribution */
|
|
if (sub(hqswb_clas , HQ_GEN_SWB) == 0 || sub(hqswb_clas , HQ_GEN_FB) == 0)
|
|
{
|
|
/* Initial bits distribution */
|
|
L_tmp1 = 0;
|
|
m_fx = 0;
|
|
for ( i = 0; i < num_env_bands ; i++)
|
|
{
|
|
L_tmp1 = L_mac0(L_tmp1, Nb[i], y[i]);
|
|
}
|
|
L_tmp1 = L_msu0(L_tmp1, fac, B);
|
|
|
|
t_fx = 0;
|
|
n = 0;
|
|
tmp = add(band_end_HQ[num_env_bands-1], shl(band_end_HQ[num_env_bands-1], 1));
|
|
exp1 = norm_s(tmp);
|
|
tmp = div_s(16384, shl(tmp, exp1));/*15 + 14 - exp1*/
|
|
exp2 = norm_s(tmp);
|
|
tmp = shl(tmp, exp2);
|
|
exp1 = add(29, sub(exp2, exp1));
|
|
|
|
for ( i = 0; i < N; i++)
|
|
{
|
|
L_tmp2 = L_sub(L_mult0(y[i], band_end_HQ[num_env_bands-1]), L_tmp1);
|
|
Rsubband_w32_fx[i] = L_mult0(extract_l(L_tmp2), Nb[i]);
|
|
move32();/*Q0*/
|
|
if (Rsubband_w32_fx[i] > 0)
|
|
{
|
|
n = add(n,Nb[i]);
|
|
Rsubband_w32_fx[i] = Mpy_32_16(Rsubband_w32_fx[i], tmp);
|
|
move32();/*exp1 - 15*/
|
|
Rsubband_w32_fx[i] = L_shl(Rsubband_w32_fx[i], sub(30, exp1));/*Q15*/
|
|
|
|
t_fx = L_add(t_fx, Rsubband_w32_fx[i]);/*Q0*/
|
|
}
|
|
else
|
|
{
|
|
Rsubband_w32_fx[i] = 0;
|
|
move32();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Initial bits distribution */
|
|
L_tmp1 = 0;
|
|
m_fx = 0;
|
|
for ( i = 0; i < N ; i++)
|
|
{
|
|
L_tmp1 = L_mac0(L_tmp1, Nb[i], y[i]);
|
|
}
|
|
L_tmp1 = L_msu0(L_tmp1, fac, B);
|
|
|
|
|
|
t_fx = 0;
|
|
n = 0;
|
|
tmp = add(band_end_HQ[N-1], shl(band_end_HQ[N-1], 1));
|
|
exp1 = norm_s(tmp);
|
|
tmp = div_s(16384, shl(tmp, exp1));/*15 + 14 - exp1*/
|
|
exp2 = norm_s(tmp);
|
|
tmp = shl(tmp, exp2);
|
|
exp1 = add(29, sub(exp2, exp1));
|
|
for ( i = 0; i < N; i++)
|
|
{
|
|
L_tmp2 = L_sub(L_mult0(y[i], band_end_HQ[N-1]), L_tmp1);
|
|
Rsubband_w32_fx[i] = L_mult0(extract_l(L_tmp2), Nb[i]);
|
|
move32();/*Q0*/
|
|
if (Rsubband_w32_fx[i] > 0)
|
|
{
|
|
n = add(n,Nb[i]);
|
|
Rsubband_w32_fx[i] = Mpy_32_16(Rsubband_w32_fx[i], tmp);
|
|
move32();/*exp1 - 15*/
|
|
Rsubband_w32_fx[i] = L_shl(Rsubband_w32_fx[i], sub(30, exp1));/*Q15*/
|
|
|
|
t_fx = L_add(t_fx, Rsubband_w32_fx[i]);/*Q0*/
|
|
}
|
|
else
|
|
{
|
|
Rsubband_w32_fx[i] = 0;
|
|
move32();
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Distribute the remaining bits to subbands with non-zero bits */
|
|
B_fx = L_shl(B, 15);
|
|
WHILE (L_sub(L_shr(L_add(t_fx, 16384), 15) , B) != 0)
|
|
{
|
|
L_tmp1 = L_sub(t_fx, B_fx);
|
|
exp1 = sub(norm_l(L_tmp1), 1);
|
|
exp2 = norm_s(n);
|
|
tmp = div_s(extract_h(L_shl(L_tmp1, exp1)), shl(n, exp2));/*15 + 15 + exp1 - 16 - exp2*/
|
|
m_fx = shl(tmp, sub(exp2, exp1));/*Q14*/
|
|
|
|
t_fx = 0;
|
|
n = 0;
|
|
for ( i = 0; i < N; i++)
|
|
{
|
|
if (Rsubband_w32_fx[i] > 0)
|
|
{
|
|
Rsubband_w32_fx[i] = L_msu(Rsubband_w32_fx[i], m_fx, Nb[i]);
|
|
move32();
|
|
|
|
if (Rsubband_w32_fx[i] > 0)
|
|
{
|
|
n = add(n,Nb[i]);
|
|
|
|
t_fx = L_add(t_fx, Rsubband_w32_fx[i]);
|
|
}
|
|
else
|
|
{
|
|
Rsubband_w32_fx[i] = 0;
|
|
move32();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Bits = B;
|
|
|
|
/* Impose bit-constraints to subbands with less than minimum bits*/
|
|
t_fx = 0;
|
|
n = 0;
|
|
for ( i = 0; i < N; i++)
|
|
{
|
|
if (Rsubband_w32_fx[i] > 0)
|
|
{
|
|
test();
|
|
test();
|
|
if ((L_sub(Rsubband_w32_fx[i] , L_shl(add(bs, LNb[i]), 15)) <0) && (sub(low_rate,1) == 0))
|
|
{
|
|
Rsubband_w32_fx[i] = 0;
|
|
move32();
|
|
}
|
|
else if ( L_sub(Rsubband_w32_fx[i] , L_shl(Nb[i], 15)) <=0)
|
|
{
|
|
B = sub(B,Nb[i]);
|
|
Rsubband_w32_fx[i] = L_shl(Nb[i], 15);
|
|
move32();
|
|
}
|
|
else
|
|
{
|
|
n = add(n,Nb[i]);
|
|
t_fx = L_add(t_fx, Rsubband_w32_fx[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Distribute the remaining bits to subbands with more than 1-bit per sample */
|
|
WHILE (L_sub(L_shr(L_add(t_fx, 16384), 15) ,B) != 0)
|
|
{
|
|
L_tmp1 = L_sub(t_fx, L_shl(B, 15));
|
|
L_tmp2 = L_abs(L_tmp1);
|
|
|
|
if( n>0 )
|
|
{
|
|
exp1 = sub(norm_l(L_tmp2), 1);
|
|
exp2 = norm_s(n);
|
|
tmp = div_s(extract_h(L_shl(L_tmp2, exp1)), shl(n, exp2));/*15 + 15 + exp1 - 16 - exp2*/
|
|
m_fx = shl(tmp, sub(exp2, exp1));/*Q14*/
|
|
if (L_tmp1 < 0)
|
|
{
|
|
m_fx = negate(m_fx);
|
|
}
|
|
|
|
t_fx = 0;
|
|
n = 0;
|
|
for( i = 0; i < N; i++)
|
|
{
|
|
if (L_sub(Rsubband_w32_fx[i] , L_shl(Nb[i], 15)) > 0)
|
|
{
|
|
Rsubband_w32_fx[i] = L_msu(Rsubband_w32_fx[i], m_fx, Nb[i]);
|
|
if (L_sub(Rsubband_w32_fx[i] ,L_shl(Nb[i], 15)) > 0)
|
|
{
|
|
n = add(n,Nb[i]);
|
|
|
|
t_fx = L_add(t_fx, Rsubband_w32_fx[i]);
|
|
}
|
|
else
|
|
{
|
|
B = sub(B,Nb[i]);
|
|
|
|
Rsubband_w32_fx[i] = L_shl(Nb[i], 15);
|
|
move32();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/*In case no subband has enough bits more than 1-bit per sample, take bits off the higher subbands */
|
|
if (t_fx == 0)
|
|
{
|
|
for ( i = N-1; i >= 0; i--)
|
|
{
|
|
if (Rsubband_w32_fx[i] > 0)
|
|
{
|
|
B = add( B, Nb[i] );
|
|
Rsubband_w32_fx[i] = 0;
|
|
move32();
|
|
if ( B >= 0)
|
|
{
|
|
BREAK;
|
|
}
|
|
}
|
|
}
|
|
BREAK;
|
|
}
|
|
}
|
|
|
|
/* fine redistribution of over-allocated or under-allocated bits */
|
|
tmp = 0;
|
|
for ( i = 0; i < N; i++)
|
|
{
|
|
Rsubband[i] = extract_l(L_shr(Rsubband_w32_fx[i], 12));
|
|
tmp = add(tmp, Rsubband[i]);
|
|
}
|
|
|
|
B = Bits;
|
|
B_w16_fx = shl(B, 3);
|
|
if (sub(tmp ,B_w16_fx)>0)
|
|
{
|
|
tmp = sub(tmp, B_w16_fx);
|
|
for ( i = 0; i < N; i++)
|
|
{
|
|
if (sub(Rsubband[i], add(shl(Nb[i], 3), tmp)) >= 0)
|
|
{
|
|
Rsubband[i] = sub(Rsubband[i], tmp);
|
|
BREAK;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tmp = sub(tmp, B_w16_fx);
|
|
for ( i = 0; i < N; i++)
|
|
{
|
|
if (Rsubband[i] > 0)
|
|
{
|
|
Rsubband[i] = sub(Rsubband[i], tmp);
|
|
BREAK;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Calculate total used bits and initialize R to be used for Noise Filling */
|
|
tmp = 0;
|
|
for ( i = 0; i < N; i++)
|
|
{
|
|
tmp = add(tmp, Rsubband[i]);
|
|
R[i] = shr(Rsubband[i], 3);
|
|
}
|
|
|
|
return shr(tmp, 3);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*
|
|
* Bit_group()
|
|
*
|
|
* bit allocation in group
|
|
*-------------------------------------------------------------------*/
|
|
static void Bit_group_fx (
|
|
Word16 *y, /* i : norm of sub-band Q0*/
|
|
Word16 start_band, /* i : start band indices Q0*/
|
|
Word16 end_band, /* i : end band indices Q0*/
|
|
Word16 Bits, /* i : number of allocation bits in group Q0*/
|
|
Word16 thr, /* i : smallest bit number for allocation in group Q0*/
|
|
Word32 *Rsubband_fx, /* o : bit allocation of sub-band Q21*/
|
|
Word16 *fac_fx /* i : weight factor for norm of sub-band Q13*/
|
|
)
|
|
{
|
|
Word16 i, j, k, m, y_index[16], index[16], bit_band, band_num, norm_sum;
|
|
Word16 tmp,exp;
|
|
Word16 factor_fx;
|
|
Word32 R_temp_fx[16], R_sum_fx = 0, R_sum_org_fx = 0, Bits_avg_fx = 0;
|
|
Word32 L_tmp;
|
|
UWord32 lo;
|
|
|
|
/* initialization for bit allocation in one group*/
|
|
tmp = 6554;
|
|
move16(); /*Q15 1/5 */
|
|
IF(sub(thr,5) == 0)
|
|
{
|
|
tmp = 6554;
|
|
move16(); /*Q15 1/5 */
|
|
}
|
|
IF(sub(thr,6) == 0)
|
|
{
|
|
tmp = 5462;
|
|
move16();/*Q15 1/6 */
|
|
}
|
|
IF(sub(thr,7) == 0)
|
|
{
|
|
tmp = 4682;
|
|
move16();/*Q15 1/7 */
|
|
}
|
|
bit_band = mult(tmp, Bits); /*0+15-15=0, Q0 */
|
|
band_num = sub(end_band,start_band);
|
|
|
|
FOR( i = 0; i < band_num; i++ )
|
|
{
|
|
y_index[i] = y[add(i,start_band)];
|
|
move16();
|
|
index[i] = i;
|
|
move16();
|
|
}
|
|
|
|
/* Rearrange norm vector in decreasing order */
|
|
reordvct(y_index, band_num, index);
|
|
/* norm vector modification */
|
|
|
|
factor_fx = div_s(1, band_num);/*Q15 */
|
|
IF ( sub(thr,5) > 0 )
|
|
{
|
|
FOR ( i = 0; i < band_num; i++ )
|
|
{
|
|
L_tmp = L_mult(i,factor_fx);/*Q16 */
|
|
tmp = extract_h(L_shl(L_tmp, 13)); /*Q13 */
|
|
tmp = sub(fac_fx[1],tmp);/*Q13 */
|
|
L_tmp = L_mult(y_index[i],tmp);/*Q14 */
|
|
y_index[i] = extract_h(L_shl(L_tmp, 2));/*Q0 */
|
|
}
|
|
}
|
|
ELSE
|
|
{
|
|
FOR ( i = 0; i < band_num; i++ )
|
|
{
|
|
L_tmp = L_mult(i,factor_fx);/*Q16 */
|
|
tmp = extract_h(L_shl(L_tmp, 13)); /*Q13 */
|
|
tmp = sub(fac_fx[0],tmp);/*Q13 */
|
|
L_tmp = L_mult(y_index[i],tmp);/*Q14 */
|
|
y_index[i] = extract_h(L_shl(L_tmp, 2));/*Q0 */
|
|
}
|
|
}
|
|
|
|
/* bit allocation based on modified norm */
|
|
L_tmp = L_mult(band_num,24576);/*Q16 */
|
|
tmp = extract_h(L_shl(L_tmp,7));/*Q7 */
|
|
IF ( sub(shl(bit_band,7),tmp) >= 0 )
|
|
{
|
|
FOR ( j = 0; j < band_num; j++)
|
|
{
|
|
IF ( y_index[j] < 0 )
|
|
{
|
|
y_index[j] = 0;
|
|
move16();
|
|
}
|
|
R_temp_fx[j] = 2097152;
|
|
move16();/*Q21 = 1 move16(); */
|
|
}
|
|
|
|
i = sub(band_num,1);
|
|
norm_sum = 0;/*Q0 */
|
|
FOR (k = 0; k <= i; k++)
|
|
{
|
|
norm_sum = add(norm_sum,y_index[k]);
|
|
}
|
|
|
|
FOR (j = 0; j < band_num; j++)
|
|
{
|
|
IF(norm_sum == 0)
|
|
{
|
|
FOR (k = 0; k <= i; k++)
|
|
{
|
|
R_temp_fx[k] = 0;
|
|
move32();/*Q21 */
|
|
}
|
|
}
|
|
ELSE
|
|
{
|
|
exp = norm_s(norm_sum);
|
|
tmp = shl(norm_sum, exp);/*Q(exp) */
|
|
tmp = div_s(16384,tmp); /*Q(15+14-exp) */
|
|
Bits_avg_fx = L_mult(tmp, Bits);/*Q(30-exp) */
|
|
|
|
FOR (k = 0; k <= i; k++)
|
|
{
|
|
L_tmp = L_shl(L_deposit_l(y_index[k]),24);
|
|
Mpy_32_32_ss(Bits_avg_fx,L_tmp,&L_tmp,&lo);
|
|
|
|
R_temp_fx[k] = L_shl(L_tmp,sub(exp,2));
|
|
move32();/*Q21 */
|
|
}
|
|
}
|
|
|
|
L_tmp = L_shl(L_deposit_l(thr),21);/*Q21 */
|
|
IF ( L_sub(R_temp_fx[i],L_tmp) < 0 )
|
|
{
|
|
R_temp_fx[i] = 0;
|
|
move32();
|
|
norm_sum = sub(norm_sum,y_index[i]);
|
|
i--;
|
|
}
|
|
ELSE
|
|
{
|
|
BREAK;
|
|
}
|
|
}
|
|
}
|
|
ELSE
|
|
{
|
|
FOR ( j = 0; j < bit_band; j++ )
|
|
{
|
|
IF ( y_index[j] < 0 )
|
|
{
|
|
y_index[j] = 0;
|
|
move16();
|
|
}
|
|
R_temp_fx[j] = 2097152;
|
|
move32();/*Q21 = 1 */
|
|
}
|
|
|
|
FOR ( j = bit_band; j < band_num; j++ )
|
|
{
|
|
R_temp_fx[j] = 0;
|
|
move32();
|
|
}
|
|
|
|
norm_sum = 0;
|
|
FOR (k = 0; k < bit_band; k++)
|
|
{
|
|
norm_sum = add(norm_sum,y_index[k]);
|
|
}
|
|
|
|
i = bit_band;
|
|
FOR (j = 0; j < bit_band; j++)
|
|
{
|
|
IF(norm_sum == 0)
|
|
{
|
|
FOR (k = 0; k < i; k++)
|
|
{
|
|
R_temp_fx[k] = 0;
|
|
move32();/*Q21 */
|
|
}
|
|
}
|
|
ELSE
|
|
{
|
|
exp = norm_s(norm_sum);
|
|
tmp = shl(norm_sum, exp);/*Q(exp) */
|
|
tmp = div_s(16384,tmp); /*Q(15+14-exp) */
|
|
Bits_avg_fx = L_mult(tmp, Bits);/*Q(30-exp) */
|
|
FOR (k = 0; k < i; k++)
|
|
{
|
|
L_tmp = L_shl(L_deposit_l(y_index[k]),24);
|
|
Mpy_32_32_ss(Bits_avg_fx,L_tmp,&L_tmp,&lo);
|
|
R_temp_fx[k] = L_shl(L_tmp,sub(exp,2));
|
|
move32();/*Q21 */
|
|
}
|
|
}
|
|
R_sum_fx = 0;
|
|
L_tmp = L_shl(L_deposit_l(thr),21);/*Q21 */
|
|
FOR (k = 0; k < i; k++)
|
|
{
|
|
IF (L_sub(R_temp_fx[k],L_tmp) < 0)
|
|
{
|
|
FOR(m = k; m < i; m++)
|
|
{
|
|
norm_sum = sub(norm_sum,y_index[m]);
|
|
R_temp_fx[m] = 0;
|
|
move32();/*Q21 */
|
|
}
|
|
i = k;
|
|
BREAK;
|
|
}
|
|
ELSE
|
|
{
|
|
R_sum_fx = L_add(R_sum_fx,R_temp_fx[k]);
|
|
}
|
|
}
|
|
IF (L_sub(R_sum_fx,R_sum_org_fx) == 0)
|
|
{
|
|
BREAK;
|
|
}
|
|
|
|
R_sum_org_fx = R_sum_fx;
|
|
}
|
|
}
|
|
|
|
/* index comeback */
|
|
FOR ( k = 0 ; k < band_num; k++ )
|
|
{
|
|
j = index[k];
|
|
move16();
|
|
Rsubband_fx[add(j,start_band)] = R_temp_fx[k];
|
|
move32();
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*
|
|
* BitAllocWB()
|
|
*
|
|
* WB bit allocation
|
|
*-------------------------------------------------------------------*/
|
|
|
|
short BitAllocWB (
|
|
short *y, /* i : norm of sub-vectors */
|
|
short B, /* i : number of available bits */
|
|
short N, /* i : number of sub-vectors */
|
|
short *R, /* o : bit-allocation indicator */
|
|
short *Rsubband /* o : sub-band bit-allocation vector (Q3) */
|
|
)
|
|
{
|
|
Word16 t_fx;
|
|
Word16 i, j, k, B1, B2, B3, B_saved;
|
|
Word16 Rsum_fx, Rsum_sub_fx[3];
|
|
Word32 Ravg_sub_32_fx[3], R_diff_32_fx[2];
|
|
Word16 factor_fx[2];/*Q13 */
|
|
Word16 BANDS;
|
|
Word16 tmp,exp;
|
|
Word32 L_tmp,L_tmp1;
|
|
Word32 Rsubband_buf[NB_SFM];
|
|
UWord16 lo;
|
|
|
|
BANDS = N;
|
|
move16();
|
|
IF( sub(BANDS,SFM_N) > 0)
|
|
{
|
|
BANDS = SFM_N;
|
|
move16();
|
|
}
|
|
/* Init Rsubband to non-zero values for bands to be allocated bits */
|
|
FOR (k = 0; k < BANDS; k++)
|
|
{
|
|
Rsubband_buf[k] = 2097152;
|
|
move32();/*Q21 */
|
|
}
|
|
/* Calculate the norm sum and average of sub-band */
|
|
Rsum_sub_fx[0] = 0;
|
|
FOR ( j = 0; j < SFM_G1; j++ )
|
|
{
|
|
IF ( y[j] > 0 )
|
|
{
|
|
Rsum_sub_fx[0] = add(Rsum_sub_fx[0],y[j]);
|
|
move16();/*Q0 */
|
|
}
|
|
}
|
|
Ravg_sub_32_fx[0] = L_mult(Rsum_sub_fx[0], 2048);
|
|
move32();/*Q16 0+15+1 , q15 1/16 =2048 */
|
|
|
|
Rsum_sub_fx[1] = 0;
|
|
move32();
|
|
FOR ( j = SFM_G1; j < SFM_G1G2; j++ )
|
|
{
|
|
IF ( y[j] > 0 )
|
|
{
|
|
Rsum_sub_fx[1] = add(Rsum_sub_fx[1],y[j]);
|
|
move16();/*Q0 */
|
|
}
|
|
}
|
|
Ravg_sub_32_fx[1] = L_mult(Rsum_sub_fx[1], 4096); /*16 0+15+1 , q15 1/8 =4096 */
|
|
|
|
Rsum_sub_fx[2] = 0;
|
|
move16();
|
|
FOR ( j = SFM_G1G2; j < BANDS; j++ )
|
|
{
|
|
IF ( y[j] > 0 )
|
|
{
|
|
Rsum_sub_fx[2] = add(Rsum_sub_fx[2],y[j]);
|
|
move16();/*Q0 */
|
|
}
|
|
}
|
|
tmp = div_s(1, BANDS-SFM_G1G2); /*Q15 */
|
|
Ravg_sub_32_fx[2] = L_mult(Rsum_sub_fx[2], tmp);
|
|
move32();/*Q16 */
|
|
|
|
/* Bit allocation for every group */
|
|
tmp = add(Rsum_sub_fx[0],Rsum_sub_fx[1]);
|
|
Rsum_fx = add(tmp,Rsum_sub_fx[2]);/*Q0 */
|
|
|
|
factor_fx[0] = 16384;/*Q13 move16(); */
|
|
factor_fx[1] = 24576;/*Q13 move16(); */
|
|
{
|
|
R_diff_32_fx[0] = L_sub(Ravg_sub_32_fx[0], Ravg_sub_32_fx[1]);
|
|
move32();/*Q16 */
|
|
R_diff_32_fx[1] = L_sub(Ravg_sub_32_fx[1], Ravg_sub_32_fx[2]);
|
|
move32();/*Q16 */
|
|
|
|
IF ( L_sub(R_diff_32_fx[0],393216) < 0 && L_sub(R_diff_32_fx[1],245760) < 0 )
|
|
{
|
|
IF(Rsum_fx == 0)
|
|
{
|
|
B1 = 0;
|
|
move16();
|
|
B2 = 0;
|
|
move16();
|
|
B3 = 0;
|
|
move16();
|
|
}
|
|
ELSE
|
|
{
|
|
exp = norm_s(Rsum_fx);
|
|
tmp = shl(Rsum_fx,exp);/*Q(exp) */
|
|
tmp = div_s(16384,tmp);/*Q(15+14-exp) */
|
|
L_tmp1 = L_mult(B,Rsum_sub_fx[0]);/*Q1 */
|
|
Mpy_32_16_ss(L_tmp1,tmp,&L_tmp,&lo);
|
|
B1 = extract_h(L_shl(L_tmp,add(exp,1)));/*Q0 */
|
|
IF(L_sub(L_tmp1,L_mult(B1,Rsum_fx)) > 0 && L_sub(L_tmp1,L_mult(add(B1,1),Rsum_fx)) >= 0)
|
|
{
|
|
B1 = add(B1,1);
|
|
}
|
|
L_tmp1 = L_mult(B,Rsum_sub_fx[1]);/*Q1 */
|
|
Mpy_32_16_ss(L_tmp1,tmp,&L_tmp,&lo);
|
|
B2 = extract_h(L_shl(L_tmp,add(exp,1)));/*Q0 */
|
|
IF(L_sub(L_tmp1,L_mult(B2,Rsum_fx)) > 0 && L_sub(L_tmp1,L_mult(add(B2,1),Rsum_fx)) >= 0)
|
|
{
|
|
B2 = add(B2,1);
|
|
}
|
|
L_tmp1 = L_mult(B,Rsum_sub_fx[2]);/*Q1 */
|
|
Mpy_32_16_ss(L_tmp1,tmp,&L_tmp,&lo);
|
|
B3 = extract_h(L_shl(L_tmp,add(exp,1)));/*Q0 */
|
|
IF(L_sub(L_tmp1,L_mult(B3,Rsum_fx)) > 0 && L_sub(L_tmp1,L_mult(add(B3,1),Rsum_fx)) >= 0)
|
|
{
|
|
B3 = add(B3,1);
|
|
}
|
|
}
|
|
IF ( L_sub(Ravg_sub_32_fx[2],786432) > 0 )
|
|
{
|
|
B_saved = 0;
|
|
move16();
|
|
IF ( sub(B1,288) > 0 )
|
|
{
|
|
B_saved = sub(B1,288);
|
|
B1 = 288;
|
|
move16();
|
|
}
|
|
|
|
IF ( sub(B2,256) > 0 )
|
|
{
|
|
tmp = sub(B2,256);
|
|
B_saved = add(B_saved,tmp);
|
|
B2 = 256;
|
|
move16();
|
|
}
|
|
|
|
IF ( sub(B3,96) > 0 )
|
|
{
|
|
tmp = sub(B3,96);
|
|
B_saved = add(B_saved,tmp);
|
|
B3 = 96;
|
|
move16();
|
|
}
|
|
|
|
IF ( B_saved > 0 )
|
|
{
|
|
IF ( sub(B1,288) == 0 )
|
|
{
|
|
tmp = shr(B_saved,1);
|
|
B2 = add(B2,tmp);
|
|
tmp = sub(B,B1);
|
|
B3 = sub(tmp,B2);
|
|
}
|
|
ELSE
|
|
{
|
|
tmp = shr(B_saved,1);
|
|
B1 = add(B1,tmp);
|
|
IF ( sub(B2,256) == 0 )
|
|
{
|
|
tmp = sub(B,B1);
|
|
B3 = sub(tmp,B2);
|
|
}
|
|
ELSE
|
|
{
|
|
tmp = sub(B,B1);
|
|
B2 = sub(tmp,B3);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
factor_fx[0] = 16384;
|
|
move16();/*Q13 */
|
|
factor_fx[1] = 12288;
|
|
move16();/*Q13 */
|
|
}
|
|
ELSE
|
|
{
|
|
IF(Rsum_fx == 0)
|
|
{
|
|
B1 = 0;
|
|
move16();
|
|
B2 = 0;
|
|
move16();
|
|
B3 = B;
|
|
move16();
|
|
}
|
|
ELSE
|
|
{
|
|
exp = norm_s(Rsum_fx);
|
|
tmp = shl(Rsum_fx,exp);/*Q(exp) */
|
|
tmp = div_s(16384,tmp);/*Q(15+14-exp) */
|
|
L_tmp1 = L_mult(B,Rsum_sub_fx[0]);/*Q1 */
|
|
Mpy_32_16_ss(L_tmp1,tmp,&L_tmp,&lo);
|
|
B1 = extract_h(L_shl(L_tmp,add(exp,1)));/*Q0 */
|
|
IF(L_sub(L_tmp1,L_mult(B1,Rsum_fx)) > 0 && L_sub(L_tmp1,L_mult(add(B1,1),Rsum_fx)) >= 0)
|
|
{
|
|
B1 = add(B1,1);
|
|
}
|
|
Mpy_32_16_ss(1975684956,shl(B,5),&L_tmp1,&lo);
|
|
Mpy_32_16_ss(L_tmp1,shl(Rsum_sub_fx[1],7),&L_tmp1,&lo);
|
|
Mpy_32_16_ss(L_tmp1,tmp,&L_tmp,&lo);
|
|
B2 = extract_h(L_shl(L_tmp,sub(exp,11)));/*Q0 */
|
|
IF(L_sub(L_tmp1,L_shl(L_mult(B2,Rsum_fx),12)) > 0 && L_sub(L_add(L_tmp1,2),L_shl(L_mult(add(B2,1),Rsum_fx),12)) >= 0)
|
|
{
|
|
B2 = add(B2,1);
|
|
}
|
|
tmp = sub(B,B1);
|
|
B3 = sub(tmp,B2);
|
|
}
|
|
}
|
|
}
|
|
|
|
IF ( sub(Rsum_sub_fx[2],3) < 0 )
|
|
{
|
|
B2 = add(B2,B3);
|
|
B3 = 0;
|
|
move16();
|
|
}
|
|
|
|
/* Bit allocation in group */
|
|
Bit_group_fx( y, 0, SFM_G1, B1, 5, Rsubband_buf, factor_fx);
|
|
Bit_group_fx( y, SFM_G1, SFM_G1G2, B2, 6, Rsubband_buf, factor_fx);
|
|
Bit_group_fx( y, SFM_G1G2, BANDS, B3, 7, Rsubband_buf, factor_fx);
|
|
FOR (i = 0; i < BANDS; i++)
|
|
{
|
|
Rsubband[i] = extract_l(L_shr(Rsubband_buf[i], 18));
|
|
move16();
|
|
}
|
|
|
|
/* Calcuate total used bits and initialize R to be used for Noise Filling */
|
|
L_tmp = 0;
|
|
move32();
|
|
FOR( i = 0; i < N; i++)
|
|
{
|
|
L_tmp = L_add(L_tmp,Rsubband_buf[i]);/*Q21 */
|
|
R[i] = extract_h(L_shr(Rsubband_buf[i],5));/*Q0 */
|
|
}
|
|
t_fx = extract_h(L_shr(L_tmp, 5)); /*Q0 */
|
|
|
|
return (Word16)t_fx;
|
|
}
|
|
|
|
} // end of namespace
|