ref: 7e122394e63b3a3a07900153c4ee046b16462702
parent: e8b6ee2dbc78e332cc780f35bcfa9b63c41cb070
author: Jean-Marc Valin <jmvalin@jmvalin.ca>
date: Sat Oct 29 13:02:36 EDT 2016
Don't use hybrid "weak transients" on vowels
--- a/celt/celt_encoder.c
+++ b/celt/celt_encoder.c
@@ -226,7 +226,7 @@
static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int C,
- opus_val16 *tf_estimate, int *tf_chan, int low_rate,
+ opus_val16 *tf_estimate, int *tf_chan, int allow_weak_transients,
int *weak_transient)
{
int i;
@@ -262,7 +262,7 @@
decay of 3.3 dB/ms. This avoids having to code transients at very low
bitrate (mostly for hybrid), which can result in unstable energy and/or
partial collapse. */
- if (low_rate)
+ if (allow_weak_transients)
{
#ifdef FIXED_POINT
forward_shift = 5;
@@ -385,7 +385,7 @@
is_transient = mask_metric>200;
/* For low bitrates, define "weak transients" that need to be
handled differently to avoid partial collapse. */
- if (low_rate && is_transient && mask_metric<600) {
+ if (allow_weak_transients && is_transient && mask_metric<600) {
is_transient = 0;
*weak_transient = 1;
}
@@ -1612,8 +1612,12 @@
shortBlocks = 0;
if (st->complexity >= 1 && !st->lfe)
{
+ /* Reduces the likelihood of energy instability on fricatives at low bitrate
+ in hybrid mode. It seems like we still want to have real transients on vowels
+ though (small SILK quantization offset value). */
+ int allow_weak_transients = hybrid && effectiveBytes<15 && st->silk_info.offset >= 100;
isTransient = transient_analysis(in, N+overlap, CC,
- &tf_estimate, &tf_chan, effectiveBytes<15, &weak_transient);
+ &tf_estimate, &tf_chan, allow_weak_transients, &weak_transient);
}
if (LM>0 && ec_tell(enc)+3<=total_bits)
{