From 0869829f343f85935fac22462d228a065d0ba320 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin <jmvalin@jmvalin.ca> Date: Sun, 18 Dec 2011 22:12:42 -0500 Subject: [PATCH] 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 --- celt/celt.c | 84 ++++++++++++++++++++++++---------------------- celt/mdct.c | 6 ++-- src/opus_encoder.c | 5 +-- 3 files changed, 50 insertions(+), 45 deletions(-) diff --git a/celt/celt.c b/celt/celt.c index 0e953b21b..7645b225b 100644 --- a/celt/celt.c +++ b/celt/celt.c @@ -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) diff --git a/celt/mdct.c b/celt/mdct.c index 3193b7ccb..acccb8f36 100644 --- a/celt/mdct.c +++ b/celt/mdct.c @@ -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]; diff --git a/src/opus_encoder.c b/src/opus_encoder.c index 2a14c0750..6dee15dd0 100644 --- a/src/opus_encoder.c +++ b/src/opus_encoder.c @@ -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 -- GitLab