shithub: opus

Download patch

ref: 86101c0e84d7c92685ee02541e34623d3fbe0912
parent: 3b68a4865922d4e653130e13681f5640500486a0
author: Jean-Marc Valin <jeanmarcv@google.com>
date: Fri Jun 21 12:52:23 EDT 2024

Improve encoder allocation on tones

Compensates for the spectral leakage and the fact that we don't have
an explicit masking curve.

--- a/celt/celt_encoder.c
+++ b/celt/celt_encoder.c
@@ -991,7 +991,7 @@
       int nbEBands, int start, int end, int C, int *offsets, int lsb_depth, const opus_int16 *logN,
       int isTransient, int vbr, int constrained_vbr, const opus_int16 *eBands, int LM,
       int effectiveBytes, opus_int32 *tot_boost_, int lfe, opus_val16 *surround_dynalloc,
-      AnalysisInfo *analysis, int *importance, int *spread_weight)
+      AnalysisInfo *analysis, int *importance, int *spread_weight, opus_val16 tone_freq, opus_val32 toneishness)
 {
    int i, c;
    opus_int32 tot_boost=0;
@@ -1142,6 +1142,20 @@
          if (i>=12)
             follower[i] = HALF16(follower[i]);
       }
+      /* Compensate for Opus' under-allocation on tones. */
+      if (toneishness > QCONST32(.98f, 29)) {
+#ifdef FIXED_POINT
+         int freq_bin = PSHR32(MULT16_16(tone_freq, QCONST16(120/M_PI, 9)), 13+9);
+#else
+         int freq_bin = (int)floor(.5 + tone_freq*120/M_PI);
+#endif
+         for (i=start;i<end;i++) {
+            if (freq_bin >= eBands[i] && freq_bin <= eBands[i+1]) follower[i] += QCONST16(2., DB_SHIFT);
+            if (freq_bin >= eBands[i]-1 && freq_bin <= eBands[i+1]+1) follower[i] += QCONST16(1., DB_SHIFT);
+            if (freq_bin >= eBands[i]-2 && freq_bin <= eBands[i+1]+2) follower[i] += QCONST16(1., DB_SHIFT);
+            if (freq_bin >= eBands[i]-3 && freq_bin <= eBands[i+1]+3) follower[i] += QCONST16(.5, DB_SHIFT);
+         }
+      }
 #ifdef DISABLE_FLOAT_API
       (void)analysis;
 #else
@@ -2068,7 +2082,7 @@
 
    maxDepth = dynalloc_analysis(bandLogE, bandLogE2, oldBandE, nbEBands, start, end, C, offsets,
          st->lsb_depth, mode->logN, isTransient, st->vbr, st->constrained_vbr,
-         eBands, LM, effectiveBytes, &tot_boost, st->lfe, surround_dynalloc, &st->analysis, importance, spread_weight);
+         eBands, LM, effectiveBytes, &tot_boost, st->lfe, surround_dynalloc, &st->analysis, importance, spread_weight, tone_freq, toneishness);
 
    ALLOC(tf_res, nbEBands, int);
    /* Disable variable tf resolution for hybrid and at very low bitrate */
--