Adds a 3 Hz high-pass filter and boost allocation on leakage

Fixes two leakage problems on the wood blocks sample
- Removes DC which causes leakage with no masking
- Detect leakage by comparing short-MDCT energy to long-MDCT energy
  and boost allocation for bands with leakage
This commit is contained in:
Jean-Marc Valin 2011-12-18 22:12:42 -05:00
parent 96d7a07942
commit 0869829f34
3 changed files with 50 additions and 45 deletions

View file

@ -1325,9 +1325,44 @@ int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int f
compute_band_energies(st->mode, freq, bandE, effEnd, C, M);
amp2Log2(st->mode, effEnd, st->end, bandE, bandLogE, C);
/*for (i=0;i<17;i++)
/*for (i=0;i<21;i++)
printf("%f ", bandLogE[i]);
printf("\n");*/
ALLOC(bandLogE2, C*st->mode->nbEBands, opus_val16);
if (shortBlocks)
{
ALLOC(freq2, C*N, celt_sig);
compute_mdcts(st->mode, 0, in, freq2, CC, LM);
if (CC==2&&C==1)
{
for (i=0;i<N;i++)
freq2[i] = ADD32(HALF32(freq2[i]), HALF32(freq2[N+i]));
}
if (st->upsample != 1)
{
c=0; do
{
int bound = N/st->upsample;
for (i=0;i<bound;i++)
freq2[c*N+i] *= st->upsample;
for (;i<N;i++)
freq2[c*N+i] = 0;
} while (++c<C);
}
ALLOC(bandE2, C*st->mode->nbEBands, opus_val32);
compute_band_energies(st->mode, freq2, bandE2, effEnd, C, M);
amp2Log2(st->mode, effEnd, st->end, bandE2, bandLogE2, C);
for (i=0;i<C*st->mode->nbEBands;i++)
bandLogE2[i] += LM/2.;
} else {
for (i=0;i<C*st->mode->nbEBands;i++)
bandLogE2[i] = bandLogE[i];
}
/*for (i=0;i<C*st->mode->nbEBands;i++)
printf("%f ", MAX16(0,bandLogE[i]-bandLogE2[i]-LM/2.));
printf("\n");*/
{
opus_val16 follower[42]={0};
c=0;do
@ -1403,11 +1438,11 @@ int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int f
opus_val16 follower[42]={0};
c=0;do
{
follower[c*st->mode->nbEBands] = bandLogE[c*st->mode->nbEBands];
follower[c*st->mode->nbEBands] = bandLogE2[c*st->mode->nbEBands];
for (i=1;i<st->mode->nbEBands;i++)
follower[c*st->mode->nbEBands+i] = MIN16(follower[c*st->mode->nbEBands+i-1]+2, bandLogE[c*st->mode->nbEBands+i]);
follower[c*st->mode->nbEBands+i] = MIN16(follower[c*st->mode->nbEBands+i-1]+2, bandLogE2[c*st->mode->nbEBands+i]);
for (i=st->mode->nbEBands-2;i>=0;i--)
follower[c*st->mode->nbEBands+i] = MIN16(follower[c*st->mode->nbEBands+i], MIN16(follower[c*st->mode->nbEBands+i+1]+2, bandLogE[c*st->mode->nbEBands+i]));
follower[c*st->mode->nbEBands+i] = MIN16(follower[c*st->mode->nbEBands+i], MIN16(follower[c*st->mode->nbEBands+i+1]+2, bandLogE2[c*st->mode->nbEBands+i]));
} while (++c<2);
if (C==2)
{
@ -1423,13 +1458,13 @@ int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int f
follower[i] = MAX16(0, bandLogE[i]-follower[i]);
}
}
opus_val32 tot_boost=effectiveBytes*8/6;
opus_val32 tot_boost=(effectiveBytes*8-20-40*C)/5;
for (i=st->start;i<st->end-1;i++)
{
int width;
int boost;
follower[i] = MIN16(follower[i], QCONST16(2, DB_SHIFT));
follower[i] = MIN16(2*follower[i], i<10 ? QCONST16(4, DB_SHIFT) : QCONST16(2, DB_SHIFT));
width = C*(st->mode->eBands[i+1]-st->mode->eBands[i])<<LM;
if (width<6)
{
@ -1446,43 +1481,10 @@ int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int f
offsets[i] = boost;
}
/*for (i=st->start;i<st->end-1;i++)
printf("%f ", follower[i]);*/
//printf("%f\n", tot_boost);
#if 0
if (LM <= 1)
{
t1 = 3;
t2 = 5;
} else {
t1 = 2;
t2 = 4;
}
for (i=st->start+1;i<st->end-1;i++)
{
opus_val32 d2;
d2 = 2*bandLogE[i]-bandLogE[i-1]-bandLogE[i+1];
if (C==2)
d2 = HALF32(d2 + 2*bandLogE[i+st->mode->nbEBands]-
bandLogE[i-1+st->mode->nbEBands]-bandLogE[i+1+st->mode->nbEBands]);
#ifdef FUZZING
if((rand()&0xF)==0)
{
offsets[i] += 1;
if((rand()&0x3)==0)
offsets[i] += 1+(rand()&0x3);
}
#else
if (d2 > SHL16(t1,DB_SHIFT))
offsets[i] += 1;
if (d2 > SHL16(t2,DB_SHIFT))
offsets[i] += 1;
#endif
}
#endif
printf("%f ", follower[i]);
printf("%f\n", tot_boost);*/
}
#ifndef FIXED_POINT
//offsets[4] += 12;
//offsets[10] += 12;
if (0 && st->analysis.valid)
{
if (st->analysis.boost_amount[0]>.2)

View file

@ -109,12 +109,14 @@ void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar
int N, N2, N4;
kiss_twiddle_scalar sine;
VARDECL(kiss_fft_scalar, f);
VARDECL(kiss_fft_scalar, f2);
SAVE_STACK;
N = l->n;
N >>= shift;
N2 = N>>1;
N4 = N>>2;
ALLOC(f, N2, kiss_fft_scalar);
ALLOC(f2, N2, kiss_fft_scalar);
/* sin(x) ~= x here */
#ifdef FIXED_POINT
sine = TRIG_UPSCALE*(QCONST16(0.7853981f, 15)+N2)/N;
@ -180,12 +182,12 @@ void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar
}
/* N/4 complex FFT, down-scales by 4/N */
opus_fft(l->kfft[shift], (kiss_fft_cpx *)f, (kiss_fft_cpx *)in);
opus_fft(l->kfft[shift], (kiss_fft_cpx *)f, (kiss_fft_cpx *)f2);
/* Post-rotate */
{
/* Temp pointers to make it really clear to the compiler what we're doing */
const kiss_fft_scalar * restrict fp = in;
const kiss_fft_scalar * restrict fp = f2;
kiss_fft_scalar * restrict yp1 = out;
kiss_fft_scalar * restrict yp2 = out+stride*(N2-1);
const kiss_twiddle_scalar *t = &l->trig[0];

View file

@ -859,8 +859,9 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
{
hp_cutoff(pcm, cutoff_Hz, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs);
} else {
for (i=0;i<frame_size*st->channels;i++)
pcm_buf[total_buffer*st->channels + i] = pcm[i];
hp_cutoff(pcm, 3, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs);
/*for (i=0;i<frame_size*st->channels;i++)
pcm_buf[total_buffer*st->channels + i] = pcm[i];*/
}
#ifndef FIXED_POINT