Removed code that is no longer necessary with denorm pitch and spreading
This commit is contained in:
parent
92ae37027f
commit
095c1782c5
3 changed files with 27 additions and 272 deletions
203
libcelt/bands.c
203
libcelt/bands.c
|
@ -260,7 +260,7 @@ int compute_new_pitch(const CELTMode *m, const celt_sig_t *X, const celt_sig_t *
|
||||||
g = DIV32(SHL32(SHR32(num,shift),14),SHR32(den,shift));
|
g = DIV32(SHL32(SHR32(num,shift),14),SHR32(den,shift));
|
||||||
if (Sxy < MULT16_32_Q15(fact, MULT16_16(celt_sqrt(EPSILON+Sxx),celt_sqrt(EPSILON+Syy))))
|
if (Sxy < MULT16_32_Q15(fact, MULT16_16(celt_sqrt(EPSILON+Sxx),celt_sqrt(EPSILON+Syy))))
|
||||||
g = 0;
|
g = 0;
|
||||||
/* This MUST round down */
|
/* This MUST round down so that we don't over-estimate the gain */
|
||||||
*gain_id = EXTRACT16(SHR32(MULT16_16(20,(g-QCONST16(.5,14))),14));
|
*gain_id = EXTRACT16(SHR32(MULT16_16(20,(g-QCONST16(.5,14))),14));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -271,6 +271,7 @@ int compute_new_pitch(const CELTMode *m, const celt_sig_t *X, const celt_sig_t *
|
||||||
g = Sxy/(.1+Sxx+.03*Syy);
|
g = Sxy/(.1+Sxx+.03*Syy);
|
||||||
if (Sxy < .5*fact*celt_sqrt(1+Sxx*Syy))
|
if (Sxy < .5*fact*celt_sqrt(1+Sxx*Syy))
|
||||||
g = 0;
|
g = 0;
|
||||||
|
/* This MUST round down so that we don't over-estimate the gain */
|
||||||
*gain_id = floor(20*(g-.5));
|
*gain_id = floor(20*(g-.5));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -301,43 +302,6 @@ void apply_new_pitch(const CELTMode *m, celt_sig_t *X, const celt_sig_t *P, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute the best gain for each "pitch band" */
|
|
||||||
int compute_pitch_gain(const CELTMode *m, const celt_norm_t *X, const celt_norm_t *P, celt_pgain_t *gains)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int gain_sum = 0;
|
|
||||||
const celt_int16_t *pBands = m->pBands;
|
|
||||||
const int C = CHANNELS(m);
|
|
||||||
|
|
||||||
for (i=0;i<m->nbPBands;i++)
|
|
||||||
{
|
|
||||||
celt_word32_t Sxy=0, Sxx=0;
|
|
||||||
int j;
|
|
||||||
/* We know we're not going to overflow because Sxx can't be more than 1 (Q28) */
|
|
||||||
for (j=C*pBands[i];j<C*pBands[i+1];j++)
|
|
||||||
{
|
|
||||||
Sxy = MAC16_16(Sxy, X[j], P[j]);
|
|
||||||
Sxx = MAC16_16(Sxx, X[j], X[j]);
|
|
||||||
}
|
|
||||||
Sxy = SHR32(Sxy,2);
|
|
||||||
Sxx = SHR32(Sxx,2);
|
|
||||||
/* No negative gain allowed */
|
|
||||||
if (Sxy < 0)
|
|
||||||
Sxy = 0;
|
|
||||||
/* Not sure how that would happen, just making sure */
|
|
||||||
if (Sxy > Sxx)
|
|
||||||
Sxy = Sxx;
|
|
||||||
/* We need to be a bit conservative (multiply gain by 0.9), otherwise the
|
|
||||||
residual doesn't quantise well */
|
|
||||||
Sxy = MULT16_32_Q15(QCONST16(.99f, 15), Sxy);
|
|
||||||
/* gain = Sxy/Sxx */
|
|
||||||
gains[i] = EXTRACT16(celt_div(Sxy,ADD32(SHR32(Sxx, PGAIN_SHIFT),EPSILON)));
|
|
||||||
if (gains[i]>QCONST16(.5,15))
|
|
||||||
gain_sum++;
|
|
||||||
}
|
|
||||||
return gain_sum > 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef DISABLE_STEREO
|
#ifndef DISABLE_STEREO
|
||||||
|
|
||||||
static void stereo_band_mix(const CELTMode *m, celt_norm_t *X, const celt_ener_t *bank, int stereo_mode, int bandID, int dir)
|
static void stereo_band_mix(const CELTMode *m, celt_norm_t *X, const celt_ener_t *bank, int stereo_mode, int bandID, int dir)
|
||||||
|
@ -480,8 +444,7 @@ void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, ce
|
||||||
int i, j, remaining_bits, balance;
|
int i, j, remaining_bits, balance;
|
||||||
const celt_int16_t * restrict eBands = m->eBands;
|
const celt_int16_t * restrict eBands = m->eBands;
|
||||||
celt_norm_t * restrict norm;
|
celt_norm_t * restrict norm;
|
||||||
VARDECL(celt_norm_t, _norm); const celt_int16_t *pBands = m->pBands;
|
VARDECL(celt_norm_t, _norm);
|
||||||
int pband=-1;
|
|
||||||
int B;
|
int B;
|
||||||
SAVE_STACK;
|
SAVE_STACK;
|
||||||
|
|
||||||
|
@ -525,41 +488,12 @@ void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, ce
|
||||||
|
|
||||||
n = SHL16(celt_sqrt(eBands[i+1]-eBands[i]),11);
|
n = SHL16(celt_sqrt(eBands[i+1]-eBands[i]),11);
|
||||||
|
|
||||||
/* If pitch is in use and this eBand begins a pitch band, encode the pitch gain flag */
|
|
||||||
if (pitch_used && eBands[i]< m->pitchEnd && eBands[i] == pBands[pband+1])
|
|
||||||
{
|
|
||||||
int enabled = 1;
|
|
||||||
pband++;
|
|
||||||
if (remaining_bits >= 1<<BITRES) {
|
|
||||||
enabled = pgains[pband] > QCONST16(.5,15);
|
|
||||||
ec_enc_bits(enc, enabled, 1);
|
|
||||||
balance += 1<<BITRES;
|
|
||||||
}
|
|
||||||
if (enabled)
|
|
||||||
pgains[pband] = QCONST16(.9,15);
|
|
||||||
else
|
|
||||||
pgains[pband] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If pitch isn't available, use intra-frame prediction */
|
|
||||||
if (q==0)
|
|
||||||
{
|
|
||||||
intra_fold(m, X+eBands[i], eBands[i+1]-eBands[i], norm, P+eBands[i], eBands[i], B);
|
|
||||||
} else if (pitch_used && eBands[i] < m->pitchEnd) {
|
|
||||||
for (j=eBands[i];j<eBands[i+1];j++)
|
|
||||||
P[j] = MULT16_16_Q15(pgains[pband], P[j]);
|
|
||||||
} else {
|
|
||||||
for (j=eBands[i];j<eBands[i+1];j++)
|
|
||||||
P[j] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (q > 0)
|
if (q > 0)
|
||||||
{
|
{
|
||||||
int spread = (eBands[i] >= m->pitchEnd && fold) ? B : 0;
|
int spread = (eBands[i] >= m->pitchEnd && fold) ? B : 0;
|
||||||
alg_quant(X+eBands[i], W+eBands[i], eBands[i+1]-eBands[i], q, spread, P+eBands[i], enc);
|
alg_quant(X+eBands[i], eBands[i+1]-eBands[i], q, spread, enc);
|
||||||
} else {
|
} else {
|
||||||
for (j=eBands[i];j<eBands[i+1];j++)
|
intra_fold(m, X+eBands[i], eBands[i+1]-eBands[i], norm, X+eBands[i], eBands[i], B);
|
||||||
X[j] = P[j];
|
|
||||||
}
|
}
|
||||||
for (j=eBands[i];j<eBands[i+1];j++)
|
for (j=eBands[i];j<eBands[i+1];j++)
|
||||||
norm[j] = MULT16_16_Q15(n,X[j]);
|
norm[j] = MULT16_16_Q15(n,X[j]);
|
||||||
|
@ -576,7 +510,6 @@ void quant_bands_stereo(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t
|
||||||
celt_norm_t * restrict norm;
|
celt_norm_t * restrict norm;
|
||||||
VARDECL(celt_norm_t, _norm);
|
VARDECL(celt_norm_t, _norm);
|
||||||
const int C = CHANNELS(m);
|
const int C = CHANNELS(m);
|
||||||
const celt_int16_t *pBands = m->pBands;
|
|
||||||
int pband=-1;
|
int pband=-1;
|
||||||
int B;
|
int B;
|
||||||
celt_word16_t mid, side;
|
celt_word16_t mid, side;
|
||||||
|
@ -661,23 +594,6 @@ void quant_bands_stereo(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t
|
||||||
}
|
}
|
||||||
n = SHL16(celt_sqrt((eBands[i+1]-eBands[i])),11);
|
n = SHL16(celt_sqrt((eBands[i+1]-eBands[i])),11);
|
||||||
|
|
||||||
/* If pitch is in use and this eBand begins a pitch band, encode the pitch gain flag */
|
|
||||||
if (pitch_used && eBands[i]< m->pitchEnd && eBands[i] == pBands[pband+1])
|
|
||||||
{
|
|
||||||
int enabled = 1;
|
|
||||||
pband++;
|
|
||||||
if (remaining_bits >= 1<<BITRES) {
|
|
||||||
enabled = pgains[pband] > QCONST16(.5,15);
|
|
||||||
ec_enc_bits(enc, enabled, 1);
|
|
||||||
balance += 1<<BITRES;
|
|
||||||
remaining_bits -= 1<<BITRES;
|
|
||||||
}
|
|
||||||
if (enabled)
|
|
||||||
pgains[pband] = QCONST16(.9,15);
|
|
||||||
else
|
|
||||||
pgains[pband] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (N==2)
|
if (N==2)
|
||||||
{
|
{
|
||||||
int c2;
|
int c2;
|
||||||
|
@ -692,19 +608,6 @@ void quant_bands_stereo(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t
|
||||||
c = itheta > 8192 ? 1 : 0;
|
c = itheta > 8192 ? 1 : 0;
|
||||||
c2 = 1-c;
|
c2 = 1-c;
|
||||||
|
|
||||||
if (eBands[i] >= m->pitchEnd && fold)
|
|
||||||
{
|
|
||||||
} else if (pitch_used && eBands[i] < m->pitchEnd) {
|
|
||||||
stereo_band_mix(m, P, bandE, qb==0, i, 1);
|
|
||||||
renormalise_vector(P+C*eBands[i], Q15ONE, N, C);
|
|
||||||
renormalise_vector(P+C*eBands[i]+1, Q15ONE, N, C);
|
|
||||||
deinterleave(P+C*eBands[i], C*N);
|
|
||||||
for (j=C*eBands[i];j<C*eBands[i+1];j++)
|
|
||||||
P[j] = MULT16_16_Q15(pgains[pband], P[j]);
|
|
||||||
} else {
|
|
||||||
for (j=C*eBands[i];j<C*eBands[i+1];j++)
|
|
||||||
P[j] = 0;
|
|
||||||
}
|
|
||||||
v[0] = x2[c];
|
v[0] = x2[c];
|
||||||
v[1] = x2[c+C];
|
v[1] = x2[c+C];
|
||||||
w[0] = x2[c2];
|
w[0] = x2[c2];
|
||||||
|
@ -723,7 +626,7 @@ void quant_bands_stereo(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t
|
||||||
if (q1 > 0)
|
if (q1 > 0)
|
||||||
{
|
{
|
||||||
int spread = (eBands[i] >= m->pitchEnd && fold) ? B : 0;
|
int spread = (eBands[i] >= m->pitchEnd && fold) ? B : 0;
|
||||||
alg_quant(v, W+C*eBands[i], N, q1, spread, P+C*eBands[i]+c*N, enc);
|
alg_quant(v, N, q1, spread, enc);
|
||||||
} else {
|
} else {
|
||||||
v[0] = QCONST16(1.f, 14);
|
v[0] = QCONST16(1.f, 14);
|
||||||
v[1] = 0;
|
v[1] = 0;
|
||||||
|
@ -783,27 +686,17 @@ void quant_bands_stereo(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t
|
||||||
{
|
{
|
||||||
intra_fold(m, X+C*eBands[i], eBands[i+1]-eBands[i], norm, P+C*eBands[i], eBands[i], B);
|
intra_fold(m, X+C*eBands[i], eBands[i+1]-eBands[i], norm, P+C*eBands[i], eBands[i], B);
|
||||||
deinterleave(P+C*eBands[i], C*N);
|
deinterleave(P+C*eBands[i], C*N);
|
||||||
} else if (pitch_used && eBands[i] < m->pitchEnd) {
|
|
||||||
stereo_band_mix(m, P, bandE, qb==0, i, 1);
|
|
||||||
renormalise_vector(P+C*eBands[i], Q15ONE, N, C);
|
|
||||||
renormalise_vector(P+C*eBands[i]+1, Q15ONE, N, C);
|
|
||||||
deinterleave(P+C*eBands[i], C*N);
|
|
||||||
for (j=C*eBands[i];j<C*eBands[i+1];j++)
|
|
||||||
P[j] = MULT16_16_Q15(pgains[pband], P[j]);
|
|
||||||
} else {
|
|
||||||
for (j=C*eBands[i];j<C*eBands[i+1];j++)
|
|
||||||
P[j] = 0;
|
|
||||||
}
|
}
|
||||||
deinterleave(X+C*eBands[i], C*N);
|
deinterleave(X+C*eBands[i], C*N);
|
||||||
if (q1 > 0) {
|
if (q1 > 0) {
|
||||||
int spread = (eBands[i] >= m->pitchEnd && fold) ? B : 0;
|
int spread = (eBands[i] >= m->pitchEnd && fold) ? B : 0;
|
||||||
alg_quant(X+C*eBands[i], W+C*eBands[i], N, q1, spread, P+C*eBands[i], enc);
|
alg_quant(X+C*eBands[i], N, q1, spread, enc);
|
||||||
} else
|
} else
|
||||||
for (j=C*eBands[i];j<C*eBands[i]+N;j++)
|
for (j=C*eBands[i];j<C*eBands[i]+N;j++)
|
||||||
X[j] = P[j];
|
X[j] = P[j];
|
||||||
if (q2 > 0) {
|
if (q2 > 0) {
|
||||||
int spread = (eBands[i] >= m->pitchEnd && fold) ? B : 0;
|
int spread = (eBands[i] >= m->pitchEnd && fold) ? B : 0;
|
||||||
alg_quant(X+C*eBands[i]+N, W+C*eBands[i], N, q2, spread, P+C*eBands[i]+N, enc);
|
alg_quant(X+C*eBands[i]+N, N, q2, spread, enc);
|
||||||
} else
|
} else
|
||||||
for (j=C*eBands[i]+N;j<C*eBands[i+1];j++)
|
for (j=C*eBands[i]+N;j<C*eBands[i+1];j++)
|
||||||
X[j] = 0;
|
X[j] = 0;
|
||||||
|
@ -845,8 +738,6 @@ void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P,
|
||||||
const celt_int16_t * restrict eBands = m->eBands;
|
const celt_int16_t * restrict eBands = m->eBands;
|
||||||
celt_norm_t * restrict norm;
|
celt_norm_t * restrict norm;
|
||||||
VARDECL(celt_norm_t, _norm);
|
VARDECL(celt_norm_t, _norm);
|
||||||
const celt_int16_t *pBands = m->pBands;
|
|
||||||
int pband=-1;
|
|
||||||
int B;
|
int B;
|
||||||
SAVE_STACK;
|
SAVE_STACK;
|
||||||
|
|
||||||
|
@ -890,40 +781,12 @@ void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P,
|
||||||
|
|
||||||
n = SHL16(celt_sqrt(eBands[i+1]-eBands[i]),11);
|
n = SHL16(celt_sqrt(eBands[i+1]-eBands[i]),11);
|
||||||
|
|
||||||
/* If pitch is in use and this eBand begins a pitch band, encode the pitch gain flag */
|
|
||||||
if (pitch_used && eBands[i] < m->pitchEnd && eBands[i] == pBands[pband+1])
|
|
||||||
{
|
|
||||||
int enabled = 1;
|
|
||||||
pband++;
|
|
||||||
if (remaining_bits >= 1<<BITRES) {
|
|
||||||
enabled = ec_dec_bits(dec, 1);
|
|
||||||
balance += 1<<BITRES;
|
|
||||||
}
|
|
||||||
if (enabled)
|
|
||||||
pgains[pband] = QCONST16(.9,15);
|
|
||||||
else
|
|
||||||
pgains[pband] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If pitch isn't available, use intra-frame prediction */
|
|
||||||
if (q==0)
|
|
||||||
{
|
|
||||||
intra_fold(m, X+eBands[i], eBands[i+1]-eBands[i], norm, P+eBands[i], eBands[i], B);
|
|
||||||
} else if (pitch_used && eBands[i] < m->pitchEnd) {
|
|
||||||
for (j=eBands[i];j<eBands[i+1];j++)
|
|
||||||
P[j] = MULT16_16_Q15(pgains[pband], P[j]);
|
|
||||||
} else {
|
|
||||||
for (j=eBands[i];j<eBands[i+1];j++)
|
|
||||||
P[j] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (q > 0)
|
if (q > 0)
|
||||||
{
|
{
|
||||||
int spread = (eBands[i] >= m->pitchEnd && fold) ? B : 0;
|
int spread = (eBands[i] >= m->pitchEnd && fold) ? B : 0;
|
||||||
alg_unquant(X+eBands[i], eBands[i+1]-eBands[i], q, spread, P+eBands[i], dec);
|
alg_unquant(X+eBands[i], eBands[i+1]-eBands[i], q, spread, dec);
|
||||||
} else {
|
} else {
|
||||||
for (j=eBands[i];j<eBands[i+1];j++)
|
intra_fold(m, X+eBands[i], eBands[i+1]-eBands[i], norm, X+eBands[i], eBands[i], B);
|
||||||
X[j] = P[j];
|
|
||||||
}
|
}
|
||||||
for (j=eBands[i];j<eBands[i+1];j++)
|
for (j=eBands[i];j<eBands[i+1];j++)
|
||||||
norm[j] = MULT16_16_Q15(n,X[j]);
|
norm[j] = MULT16_16_Q15(n,X[j]);
|
||||||
|
@ -940,7 +803,6 @@ void unquant_bands_stereo(const CELTMode *m, celt_norm_t * restrict X, celt_norm
|
||||||
celt_norm_t * restrict norm;
|
celt_norm_t * restrict norm;
|
||||||
VARDECL(celt_norm_t, _norm);
|
VARDECL(celt_norm_t, _norm);
|
||||||
const int C = CHANNELS(m);
|
const int C = CHANNELS(m);
|
||||||
const celt_int16_t *pBands = m->pBands;
|
|
||||||
int pband=-1;
|
int pband=-1;
|
||||||
int B;
|
int B;
|
||||||
celt_word16_t mid, side;
|
celt_word16_t mid, side;
|
||||||
|
@ -1014,22 +876,6 @@ void unquant_bands_stereo(const CELTMode *m, celt_norm_t * restrict X, celt_norm
|
||||||
}
|
}
|
||||||
n = SHL16(celt_sqrt((eBands[i+1]-eBands[i])),11);
|
n = SHL16(celt_sqrt((eBands[i+1]-eBands[i])),11);
|
||||||
|
|
||||||
/* If pitch is in use and this eBand begins a pitch band, encode the pitch gain flag */
|
|
||||||
if (pitch_used && eBands[i]< m->pitchEnd && eBands[i] == pBands[pband+1])
|
|
||||||
{
|
|
||||||
int enabled = 1;
|
|
||||||
pband++;
|
|
||||||
if (remaining_bits >= 1<<BITRES) {
|
|
||||||
enabled = ec_dec_bits(dec, 1);
|
|
||||||
balance += 1<<BITRES;
|
|
||||||
remaining_bits -= 1<<BITRES;
|
|
||||||
}
|
|
||||||
if (enabled)
|
|
||||||
pgains[pband] = QCONST16(.9,15);
|
|
||||||
else
|
|
||||||
pgains[pband] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (N==2)
|
if (N==2)
|
||||||
{
|
{
|
||||||
int c2;
|
int c2;
|
||||||
|
@ -1044,19 +890,6 @@ void unquant_bands_stereo(const CELTMode *m, celt_norm_t * restrict X, celt_norm
|
||||||
c = itheta > 8192 ? 1 : 0;
|
c = itheta > 8192 ? 1 : 0;
|
||||||
c2 = 1-c;
|
c2 = 1-c;
|
||||||
|
|
||||||
if (eBands[i] >= m->pitchEnd && fold)
|
|
||||||
{
|
|
||||||
} else if (pitch_used && eBands[i] < m->pitchEnd) {
|
|
||||||
stereo_band_mix(m, P, bandE, qb==0, i, 1);
|
|
||||||
renormalise_vector(P+C*eBands[i], Q15ONE, N, C);
|
|
||||||
renormalise_vector(P+C*eBands[i]+1, Q15ONE, N, C);
|
|
||||||
deinterleave(P+C*eBands[i], C*N);
|
|
||||||
for (j=C*eBands[i];j<C*eBands[i+1];j++)
|
|
||||||
P[j] = MULT16_16_Q15(pgains[pband], P[j]);
|
|
||||||
} else {
|
|
||||||
for (j=C*eBands[i];j<C*eBands[i+1];j++)
|
|
||||||
P[j] = 0;
|
|
||||||
}
|
|
||||||
v[0] = x2[c];
|
v[0] = x2[c];
|
||||||
v[1] = x2[c+C];
|
v[1] = x2[c+C];
|
||||||
w[0] = x2[c2];
|
w[0] = x2[c2];
|
||||||
|
@ -1075,7 +908,7 @@ void unquant_bands_stereo(const CELTMode *m, celt_norm_t * restrict X, celt_norm
|
||||||
if (q1 > 0)
|
if (q1 > 0)
|
||||||
{
|
{
|
||||||
int spread = (eBands[i] >= m->pitchEnd && fold) ? B : 0;
|
int spread = (eBands[i] >= m->pitchEnd && fold) ? B : 0;
|
||||||
alg_unquant(v, N, q1, spread, P+C*eBands[i]+c*N, dec);
|
alg_unquant(v, N, q1, spread, dec);
|
||||||
} else {
|
} else {
|
||||||
v[0] = QCONST16(1.f, 14);
|
v[0] = QCONST16(1.f, 14);
|
||||||
v[1] = 0;
|
v[1] = 0;
|
||||||
|
@ -1130,29 +963,19 @@ void unquant_bands_stereo(const CELTMode *m, celt_norm_t * restrict X, celt_norm
|
||||||
{
|
{
|
||||||
intra_fold(m, X+C*eBands[i], eBands[i+1]-eBands[i], norm, P+C*eBands[i], eBands[i], B);
|
intra_fold(m, X+C*eBands[i], eBands[i+1]-eBands[i], norm, P+C*eBands[i], eBands[i], B);
|
||||||
deinterleave(P+C*eBands[i], C*N);
|
deinterleave(P+C*eBands[i], C*N);
|
||||||
} else if (pitch_used && eBands[i] < m->pitchEnd) {
|
|
||||||
stereo_band_mix(m, P, bandE, qb==0, i, 1);
|
|
||||||
renormalise_vector(P+C*eBands[i], Q15ONE, N, C);
|
|
||||||
renormalise_vector(P+C*eBands[i]+1, Q15ONE, N, C);
|
|
||||||
deinterleave(P+C*eBands[i], C*N);
|
|
||||||
for (j=C*eBands[i];j<C*eBands[i+1];j++)
|
|
||||||
P[j] = MULT16_16_Q15(pgains[pband], P[j]);
|
|
||||||
} else {
|
|
||||||
for (j=C*eBands[i];j<C*eBands[i+1];j++)
|
|
||||||
P[j] = 0;
|
|
||||||
}
|
}
|
||||||
deinterleave(X+C*eBands[i], C*N);
|
deinterleave(X+C*eBands[i], C*N);
|
||||||
if (q1 > 0)
|
if (q1 > 0)
|
||||||
{
|
{
|
||||||
int spread = (eBands[i] >= m->pitchEnd && fold) ? B : 0;
|
int spread = (eBands[i] >= m->pitchEnd && fold) ? B : 0;
|
||||||
alg_unquant(X+C*eBands[i], N, q1, spread, P+C*eBands[i], dec);
|
alg_unquant(X+C*eBands[i], N, q1, spread, dec);
|
||||||
} else
|
} else
|
||||||
for (j=C*eBands[i];j<C*eBands[i]+N;j++)
|
for (j=C*eBands[i];j<C*eBands[i]+N;j++)
|
||||||
X[j] = P[j];
|
X[j] = P[j];
|
||||||
if (q2 > 0)
|
if (q2 > 0)
|
||||||
{
|
{
|
||||||
int spread = (eBands[i] >= m->pitchEnd && fold) ? B : 0;
|
int spread = (eBands[i] >= m->pitchEnd && fold) ? B : 0;
|
||||||
alg_unquant(X+C*eBands[i]+N, N, q2, spread, P+C*eBands[i]+N, dec);
|
alg_unquant(X+C*eBands[i]+N, N, q2, spread, dec);
|
||||||
} else
|
} else
|
||||||
for (j=C*eBands[i]+N;j<C*eBands[i+1];j++)
|
for (j=C*eBands[i]+N;j<C*eBands[i+1];j++)
|
||||||
X[j] = 0;
|
X[j] = 0;
|
||||||
|
|
92
libcelt/vq.c
92
libcelt/vq.c
|
@ -95,11 +95,10 @@ static void exp_rotation(celt_norm_t *X, int len, int dir, int stride, int K)
|
||||||
|
|
||||||
/** Takes the pitch vector and the decoded residual vector, computes the gain
|
/** Takes the pitch vector and the decoded residual vector, computes the gain
|
||||||
that will give ||p+g*y||=1 and mixes the residual with the pitch. */
|
that will give ||p+g*y||=1 and mixes the residual with the pitch. */
|
||||||
static void mix_pitch_and_residual(int * restrict iy, celt_norm_t * restrict X, int N, int K, const celt_norm_t * restrict P)
|
static void mix_pitch_and_residual(int * restrict iy, celt_norm_t * restrict X, int N, int K)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
celt_word32_t Ryp, Ryy, Rpp;
|
celt_word32_t Ryy;
|
||||||
celt_word16_t ryp, ryy, rpp;
|
|
||||||
celt_word32_t g;
|
celt_word32_t g;
|
||||||
VARDECL(celt_norm_t, y);
|
VARDECL(celt_norm_t, y);
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
|
@ -111,39 +110,25 @@ static void mix_pitch_and_residual(int * restrict iy, celt_norm_t * restrict X,
|
||||||
#endif
|
#endif
|
||||||
ALLOC(y, N, celt_norm_t);
|
ALLOC(y, N, celt_norm_t);
|
||||||
|
|
||||||
Rpp = 0;
|
|
||||||
i=0;
|
i=0;
|
||||||
do {
|
|
||||||
Rpp = MAC16_16(Rpp,P[i],P[i]);
|
|
||||||
y[i] = SHL16(iy[i],yshift);
|
|
||||||
} while (++i < N);
|
|
||||||
|
|
||||||
Ryp = 0;
|
|
||||||
Ryy = 0;
|
Ryy = 0;
|
||||||
/* If this doesn't generate a dual MAC (on supported archs), fire the compiler guy */
|
|
||||||
i=0;
|
|
||||||
do {
|
do {
|
||||||
Ryp = MAC16_16(Ryp, y[i], P[i]);
|
y[i] = SHL16(iy[i],yshift);
|
||||||
Ryy = MAC16_16(Ryy, y[i], y[i]);
|
Ryy = MAC16_16(Ryy, y[i], y[i]);
|
||||||
} while (++i < N);
|
} while (++i < N);
|
||||||
|
|
||||||
ryp = ROUND16(Ryp,14);
|
g = MULT16_32_Q15(celt_sqrt(Ryy), celt_rcp(SHR32(Ryy,9)));
|
||||||
ryy = ROUND16(Ryy,14);
|
|
||||||
rpp = ROUND16(Rpp,14);
|
|
||||||
/* g = (sqrt(Ryp^2 + Ryy - Rpp*Ryy)-Ryp)/Ryy */
|
|
||||||
g = MULT16_32_Q15(celt_sqrt(MAC16_16(Ryy, ryp,ryp) - MULT16_16(ryy,rpp)) - ryp,
|
|
||||||
celt_rcp(SHR32(Ryy,9)));
|
|
||||||
|
|
||||||
i=0;
|
i=0;
|
||||||
do
|
do
|
||||||
X[i] = ADD16(P[i], ROUND16(MULT16_16(y[i], g),11));
|
X[i] = ROUND16(MULT16_16(y[i], g),11);
|
||||||
while (++i < N);
|
while (++i < N);
|
||||||
|
|
||||||
RESTORE_STACK;
|
RESTORE_STACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, int spread, celt_norm_t *P, ec_enc *enc)
|
void alg_quant(celt_norm_t *X, int N, int K, int spread, ec_enc *enc)
|
||||||
{
|
{
|
||||||
VARDECL(celt_norm_t, y);
|
VARDECL(celt_norm_t, y);
|
||||||
VARDECL(int, iy);
|
VARDECL(int, iy);
|
||||||
|
@ -152,8 +137,7 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, int spread, celt_no
|
||||||
celt_word16_t s;
|
celt_word16_t s;
|
||||||
int pulsesLeft;
|
int pulsesLeft;
|
||||||
celt_word32_t sum;
|
celt_word32_t sum;
|
||||||
celt_word32_t xy, yy, yp;
|
celt_word32_t xy, yy;
|
||||||
celt_word16_t Rpp;
|
|
||||||
int N_1; /* Inverse of N, in Q14 format (even for float) */
|
int N_1; /* Inverse of N, in Q14 format (even for float) */
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
int yshift;
|
int yshift;
|
||||||
|
@ -175,23 +159,19 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, int spread, celt_no
|
||||||
|
|
||||||
sum = 0;
|
sum = 0;
|
||||||
j=0; do {
|
j=0; do {
|
||||||
X[j] -= P[j];
|
|
||||||
if (X[j]>0)
|
if (X[j]>0)
|
||||||
signx[j]=1;
|
signx[j]=1;
|
||||||
else {
|
else {
|
||||||
signx[j]=-1;
|
signx[j]=-1;
|
||||||
X[j]=-X[j];
|
X[j]=-X[j];
|
||||||
P[j]=-P[j];
|
|
||||||
}
|
}
|
||||||
iy[j] = 0;
|
iy[j] = 0;
|
||||||
y[j] = 0;
|
y[j] = 0;
|
||||||
sum = MAC16_16(sum, P[j],P[j]);
|
|
||||||
} while (++j<N);
|
} while (++j<N);
|
||||||
Rpp = ROUND16(sum, NORM_SHIFT);
|
|
||||||
|
|
||||||
celt_assert2(Rpp<=NORM_SCALING, "Rpp should never have a norm greater than unity");
|
celt_assert2(Rpp<=NORM_SCALING, "Rpp should never have a norm greater than unity");
|
||||||
|
|
||||||
xy = yy = yp = 0;
|
xy = yy = 0;
|
||||||
|
|
||||||
pulsesLeft = K;
|
pulsesLeft = K;
|
||||||
|
|
||||||
|
@ -228,14 +208,13 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, int spread, celt_no
|
||||||
y[j] = SHL16(iy[j],yshift);
|
y[j] = SHL16(iy[j],yshift);
|
||||||
yy = MAC16_16(yy, y[j],y[j]);
|
yy = MAC16_16(yy, y[j],y[j]);
|
||||||
xy = MAC16_16(xy, X[j],y[j]);
|
xy = MAC16_16(xy, X[j],y[j]);
|
||||||
yp += P[j]*y[j];
|
|
||||||
y[j] *= 2;
|
y[j] *= 2;
|
||||||
pulsesLeft -= iy[j];
|
pulsesLeft -= iy[j];
|
||||||
} while (++j<N);
|
} while (++j<N);
|
||||||
}
|
}
|
||||||
celt_assert2(pulsesLeft>=1, "Allocated too many pulses in the quick pass");
|
celt_assert2(pulsesLeft>=1, "Allocated too many pulses in the quick pass");
|
||||||
|
|
||||||
while (pulsesLeft > 1)
|
while (pulsesLeft > 0)
|
||||||
{
|
{
|
||||||
int pulsesAtOnce=1;
|
int pulsesAtOnce=1;
|
||||||
int best_id;
|
int best_id;
|
||||||
|
@ -292,7 +271,6 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, int spread, celt_no
|
||||||
xy = xy + MULT16_16(s,X[j]);
|
xy = xy + MULT16_16(s,X[j]);
|
||||||
/* We're multiplying y[j] by two so we don't have to do it here */
|
/* We're multiplying y[j] by two so we don't have to do it here */
|
||||||
yy = yy + MULT16_16(s,y[j]);
|
yy = yy + MULT16_16(s,y[j]);
|
||||||
yp = yp + MULT16_16(s, P[j]);
|
|
||||||
|
|
||||||
/* Only now that we've made the final choice, update y/iy */
|
/* Only now that we've made the final choice, update y/iy */
|
||||||
/* Multiplying y[j] by 2 so we don't have to do it everywhere else */
|
/* Multiplying y[j] by 2 so we don't have to do it everywhere else */
|
||||||
|
@ -300,54 +278,8 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, int spread, celt_no
|
||||||
iy[j] += is;
|
iy[j] += is;
|
||||||
pulsesLeft -= pulsesAtOnce;
|
pulsesLeft -= pulsesAtOnce;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pulsesLeft > 0)
|
|
||||||
{
|
|
||||||
celt_word16_t g;
|
|
||||||
celt_word16_t best_num = -VERY_LARGE16;
|
|
||||||
celt_word16_t best_den = 0;
|
|
||||||
int best_id = 0;
|
|
||||||
celt_word16_t magnitude = SHL16(1, yshift);
|
|
||||||
|
|
||||||
/* The squared magnitude term gets added anyway, so we might as well
|
|
||||||
add it outside the loop */
|
|
||||||
yy = MAC16_16(yy, magnitude,magnitude);
|
|
||||||
j=0;
|
j=0;
|
||||||
do {
|
do {
|
||||||
celt_word16_t Rxy, Ryy, Ryp;
|
|
||||||
celt_word16_t num;
|
|
||||||
/* Select sign based on X[j] alone */
|
|
||||||
s = magnitude;
|
|
||||||
/* Temporary sums of the new pulse(s) */
|
|
||||||
Rxy = ROUND16(MAC16_16(xy, s,X[j]), 14);
|
|
||||||
/* We're multiplying y[j] by two so we don't have to do it here */
|
|
||||||
Ryy = ROUND16(MAC16_16(yy, s,y[j]), 14);
|
|
||||||
Ryp = ROUND16(MAC16_16(yp, s,P[j]), 14);
|
|
||||||
|
|
||||||
/* Compute the gain such that ||p + g*y|| = 1
|
|
||||||
...but instead, we compute g*Ryy to avoid dividing */
|
|
||||||
g = celt_psqrt(MULT16_16(Ryp,Ryp) + MULT16_16(Ryy,QCONST16(1.f,14)-Rpp)) - Ryp;
|
|
||||||
/* Knowing that gain, what's the error: (x-g*y)^2
|
|
||||||
(result is negated and we discard x^2 because it's constant) */
|
|
||||||
/* score = 2*g*Rxy - g*g*Ryy;*/
|
|
||||||
#ifdef FIXED_POINT
|
|
||||||
/* No need to multiply Rxy by 2 because we did it earlier */
|
|
||||||
num = MULT16_16_Q15(ADD16(SUB16(Rxy,g),Rxy),g);
|
|
||||||
#else
|
|
||||||
num = g*(2*Rxy-g);
|
|
||||||
#endif
|
|
||||||
if (MULT16_16(best_den, num) > MULT16_16(Ryy, best_num))
|
|
||||||
{
|
|
||||||
best_den = Ryy;
|
|
||||||
best_num = num;
|
|
||||||
best_id = j;
|
|
||||||
}
|
|
||||||
} while (++j<N);
|
|
||||||
iy[best_id] += 1;
|
|
||||||
}
|
|
||||||
j=0;
|
|
||||||
do {
|
|
||||||
P[j] = MULT16_16(signx[j],P[j]);
|
|
||||||
X[j] = MULT16_16(signx[j],X[j]);
|
X[j] = MULT16_16(signx[j],X[j]);
|
||||||
if (signx[j] < 0)
|
if (signx[j] < 0)
|
||||||
iy[j] = -iy[j];
|
iy[j] = -iy[j];
|
||||||
|
@ -356,7 +288,7 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, int spread, celt_no
|
||||||
|
|
||||||
/* Recompute the gain in one pass to reduce the encoder-decoder mismatch
|
/* Recompute the gain in one pass to reduce the encoder-decoder mismatch
|
||||||
due to the recursive computation used in quantisation. */
|
due to the recursive computation used in quantisation. */
|
||||||
mix_pitch_and_residual(iy, X, N, K, P);
|
mix_pitch_and_residual(iy, X, N, K);
|
||||||
if (spread)
|
if (spread)
|
||||||
exp_rotation(X, N, -1, spread, K);
|
exp_rotation(X, N, -1, spread, K);
|
||||||
RESTORE_STACK;
|
RESTORE_STACK;
|
||||||
|
@ -365,14 +297,14 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, int spread, celt_no
|
||||||
|
|
||||||
/** Decode pulse vector and combine the result with the pitch vector to produce
|
/** Decode pulse vector and combine the result with the pitch vector to produce
|
||||||
the final normalised signal in the current band. */
|
the final normalised signal in the current band. */
|
||||||
void alg_unquant(celt_norm_t *X, int N, int K, int spread, celt_norm_t *P, ec_dec *dec)
|
void alg_unquant(celt_norm_t *X, int N, int K, int spread, ec_dec *dec)
|
||||||
{
|
{
|
||||||
VARDECL(int, iy);
|
VARDECL(int, iy);
|
||||||
SAVE_STACK;
|
SAVE_STACK;
|
||||||
K = get_pulses(K);
|
K = get_pulses(K);
|
||||||
ALLOC(iy, N, int);
|
ALLOC(iy, N, int);
|
||||||
decode_pulses(iy, N, K, dec);
|
decode_pulses(iy, N, K, dec);
|
||||||
mix_pitch_and_residual(iy, X, N, K, P);
|
mix_pitch_and_residual(iy, X, N, K);
|
||||||
if (spread)
|
if (spread)
|
||||||
exp_rotation(X, N, -1, spread, K);
|
exp_rotation(X, N, -1, spread, K);
|
||||||
RESTORE_STACK;
|
RESTORE_STACK;
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
* @param p Pitch vector (it is assumed that p+x is a unit vector)
|
* @param p Pitch vector (it is assumed that p+x is a unit vector)
|
||||||
* @param enc Entropy encoder state
|
* @param enc Entropy encoder state
|
||||||
*/
|
*/
|
||||||
void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, int spread, celt_norm_t *P, ec_enc *enc);
|
void alg_quant(celt_norm_t *X, int N, int K, int spread, ec_enc *enc);
|
||||||
|
|
||||||
/** Algebraic pulse decoder
|
/** Algebraic pulse decoder
|
||||||
* @param x Decoded normalised spectrum (returned)
|
* @param x Decoded normalised spectrum (returned)
|
||||||
|
@ -59,7 +59,7 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, int spread, celt_no
|
||||||
* @param p Pitch vector (automatically added to x)
|
* @param p Pitch vector (automatically added to x)
|
||||||
* @param dec Entropy decoder state
|
* @param dec Entropy decoder state
|
||||||
*/
|
*/
|
||||||
void alg_unquant(celt_norm_t *X, int N, int K, int spread, celt_norm_t *P, ec_dec *dec);
|
void alg_unquant(celt_norm_t *X, int N, int K, int spread, ec_dec *dec);
|
||||||
|
|
||||||
celt_word16_t renormalise_vector(celt_norm_t *X, celt_word16_t value, int N, int stride);
|
celt_word16_t renormalise_vector(celt_norm_t *X, celt_word16_t value, int N, int stride);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue