diff options
author | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2011-11-08 09:02:25 +0400 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2012-03-06 05:45:12 +0400 |
commit | 3f4a5aa5e7dfe74faa169c7131e45b67877af111 (patch) | |
tree | e89bdee824b252d3954d8538a2dcbf675825d210 | |
parent | ce8768893864fc30a3c2463f87e9033f8b42c023 (diff) |
Implements a better transient metric for VBR
-rw-r--r-- | celt/celt.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/celt/celt.c b/celt/celt.c index c608b354..dec370bd 100644 --- a/celt/celt.c +++ b/celt/celt.c @@ -292,7 +292,7 @@ static inline opus_val16 SIG2WORD16(celt_sig x) } static int transient_analysis(const opus_val32 * restrict in, int len, int C, - int overlap) + int overlap, opus_val16 *tf_estimate) { int i; VARDECL(opus_val16, tmp); @@ -300,6 +300,8 @@ static int transient_analysis(const opus_val32 * restrict in, int len, int C, int is_transient = 0; int block; int N; + opus_val16 maxbin; + opus_val32 L1, L2, tf_tmp; VARDECL(opus_val16, bins); SAVE_STACK; ALLOC(tmp, len, opus_val16); @@ -335,6 +337,7 @@ static int transient_analysis(const opus_val32 * restrict in, int len, int C, for (i=0;i<12;i++) tmp[i] = 0; + maxbin=0; for (i=0;i<N;i++) { int j; @@ -342,13 +345,20 @@ static int transient_analysis(const opus_val32 * restrict in, int len, int C, for (j=0;j<block;j++) max_abs = MAX16(max_abs, ABS16(tmp[i*block+j])); bins[i] = max_abs; + maxbin = MAX16(maxbin, bins[i]); } + L1=0; + L2=0; for (i=0;i<N;i++) { int j; int conseq=0; opus_val16 t1, t2, t3; + opus_val16 tmp_bin; + tmp_bin = bins[i]+MULT16_16_Q15(QCONST16(.05f,15),maxbin); + L1 += EXTEND32(tmp_bin); + L2 += SHR32(MULT16_16(tmp_bin, tmp_bin), 4); t1 = MULT16_16_Q15(QCONST16(.15f, 15), bins[i]); t2 = MULT16_16_Q15(QCONST16(.4f, 15), bins[i]); t3 = MULT16_16_Q15(QCONST16(.15f, 15), bins[i]); @@ -374,6 +384,9 @@ static int transient_analysis(const opus_val32 * restrict in, int len, int C, if (conseq>=7) is_transient=1; } + /* sqrt(L2*N)/L1 */ + tf_tmp = SHL32(DIV32( SHL32(EXTEND32(celt_sqrt(SHR16(L2,4) * N)), 14), ADD32(EPSILON, L1)), 4); + *tf_estimate = MAX16(QCONST16(1.f, 14), EXTRACT16(MIN16(QCONST32(1.99, 14), tf_tmp))); RESTORE_STACK; #ifdef FUZZING is_transient = rand()&0x1; @@ -916,6 +929,7 @@ int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int f int anti_collapse_rsv; int anti_collapse_on=0; int silence=0; + opus_val16 tf_estimate; ALLOC_STACK; if (nbCompressedBytes<2 || pcm==NULL) @@ -1214,7 +1228,7 @@ int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int f if (st->complexity > 1) { isTransient = transient_analysis(in, N+st->overlap, CC, - st->overlap); + st->overlap, &tf_estimate); if (isTransient) shortBlocks = M; } @@ -1378,15 +1392,11 @@ int celt_encode_with_ec(CELTEncoder * restrict st, const opus_val16 * pcm, int f if (st->constrained_vbr) target += (st->vbr_offset>>lm_diff); - /* Shortblocks get a large boost in bitrate, but since they - are uncommon long blocks are not greatly affected */ - if (shortBlocks || tf_sum < -2*(st->end-st->start)) - target = 7*target/4; - else if (tf_sum < -(st->end-st->start)) - target = 3*target/2; - else if (M > 1) - target-=(target+14)/28; - +#ifdef FIXED_POINT + target = SHL32(MULT16_32_Q15(target, SUB16(tf_estimate, QCONST16(0.05, 14))),1); +#else + target *= tf_estimate-.05; +#endif /* The current offset is removed from the target and the space used so far is added*/ target=target+tell; |