diff options
author | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2013-05-07 00:02:31 +0400 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2013-05-07 00:02:31 +0400 |
commit | d2c484b5e76f0d02b804b81e30672efa771081da (patch) | |
tree | 60408c55c2b1046fa3d77c6899c8620ad047a95e | |
parent | a4dccd3f659eb60b8b3caa8b04688246851454bf (diff) |
Adds spreading to the surround masking computation
This avoids a single low-energy band from changing the masking results.
-rw-r--r-- | celt/celt_encoder.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/celt/celt_encoder.c b/celt/celt_encoder.c index 2030ad08..66de1ba2 100644 --- a/celt/celt_encoder.c +++ b/celt/celt_encoder.c @@ -1411,13 +1411,23 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, st->energy_save[i]=bandLogE[i]-offset; st->energy_save=NULL; } + /* This computes how much masking takes place between surround channels */ if (st->energy_mask&&!st->lfe) { opus_val32 mask_avg=0; opus_val16 offset = shortBlocks?HALF16(SHL16(LM, DB_SHIFT)):0; for (c=0;c<C;c++) + { + opus_val16 followE, followMask; + followE = followMask = -QCONST16(14.f, DB_SHIFT); for(i=0;i<st->end;i++) - mask_avg += bandLogE[nbEBands*c+i]-offset-st->energy_mask[nbEBands*c+i]; + { + /* We use a simple follower to approximate the masking spreading function. */ + followE = MAX16(followE-QCONST16(1.f, DB_SHIFT), bandLogE[nbEBands*c+i]-offset); + followMask = MAX16(followMask-QCONST16(1.f, DB_SHIFT), st->energy_mask[nbEBands*c+i]); + mask_avg += followE-followMask; + } + } surround_masking = DIV32_16(mask_avg,C*st->end) + QCONST16(.0f, DB_SHIFT); surround_masking = MIN16(MAX16(surround_masking,-QCONST16(1.5f, DB_SHIFT)), 0); } |