shithub: opus

Download patch

ref: 278389defeeb9ea26100ca8f4783f44c9b446fa5
parent: 74de3a580cca34a855c2846bf249eb224f6e9658
author: Jean-Marc Valin <[email protected]>
date: Thu May 16 22:03:33 EDT 2013

Automatic bandwidth decisions get more conservative as rate increases.

This should prevent errors in the bandwidth detection from affecting quality
when we have enough bits to be close to transparent.

--- a/celt/celt.h
+++ b/celt/celt.h
@@ -58,7 +58,6 @@
    opus_val16 activity;
    opus_val16 music_prob;
    int        bandwidth;
-   int        opus_bandwidth;
 }AnalysisInfo;
 
 #define __celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr)))
--- a/src/analysis.c
+++ b/src/analysis.c
@@ -575,19 +575,7 @@
        printf("%f ", features[i]);
     printf("\n");*/
 
-    if (bandwidth<=12)
-       tonal->opus_bandwidth = OPUS_BANDWIDTH_NARROWBAND;
-    else if (bandwidth<=14)
-       tonal->opus_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
-    else if (bandwidth<=16)
-       tonal->opus_bandwidth = OPUS_BANDWIDTH_WIDEBAND;
-    else if (bandwidth<=18)
-       tonal->opus_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
-    else
-       tonal->opus_bandwidth = OPUS_BANDWIDTH_FULLBAND;
-
     info->bandwidth = bandwidth;
-    info->opus_bandwidth = tonal->opus_bandwidth;
     /*printf("%d %d\n", info->bandwidth, info->opus_bandwidth);*/
     info->noisiness = frame_noisiness;
     info->valid = 1;
--- a/src/analysis.h
+++ b/src/analysis.h
@@ -60,7 +60,6 @@
    int last_music;
    int last_transition;
    int count;
-   int opus_bandwidth;
    opus_val32   subframe_mem[3];
    int analysis_offset;
    float pspeech[DETECT_SIZE];
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -941,9 +941,21 @@
     st->detected_bandwidth = 0;
     if (analysis_info->valid)
     {
+       int analysis_bandwidth;
        if (st->signal_type == OPUS_AUTO)
           st->voice_ratio = (int)floor(.5+100*(1-analysis_info->music_prob));
-       st->detected_bandwidth = analysis_info->opus_bandwidth;
+
+       analysis_bandwidth = analysis_info->bandwidth;
+       if (analysis_bandwidth<=12)
+          st->detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND;
+       else if (analysis_bandwidth<=14)
+          st->detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
+       else if (analysis_bandwidth<=16)
+          st->detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND;
+       else if (analysis_bandwidth<=18)
+          st->detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
+       else
+          st->detected_bandwidth = OPUS_BANDWIDTH_FULLBAND;
     }
 #endif
 
@@ -1217,12 +1229,24 @@
     /* Use detected bandwidth to reduce the encoded bandwidth. */
     if (st->detected_bandwidth && st->user_bandwidth == OPUS_AUTO)
     {
-       /* When operating in SILK/hybrid mode, we don't go below wideband to avoid
-          more complicated switches that require redundancy */
-       if (st->mode == MODE_CELT_ONLY)
-          st->bandwidth = IMIN(st->bandwidth, st->detected_bandwidth);
+       int min_detected_bandwidth;
+       /* Makes bandwidth detection more conservative just in case the detector
+          gets it wrong when we could have coded a high bandwidth transparently.
+          When operating in SILK/hybrid mode, we don't go below wideband to avoid
+          more complicated switches that require redundancy. */
+       if (st->bitrate_bps <= 18000*st->stream_channels && st->mode == MODE_CELT_ONLY)
+          min_detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND;
+       else if (st->bitrate_bps <= 24000*st->stream_channels && st->mode == MODE_CELT_ONLY)
+          min_detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
+       else if (st->bitrate_bps <= 30000*st->stream_channels)
+          min_detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND;
+       else if (st->bitrate_bps <= 44000*st->stream_channels)
+          min_detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
        else
-          st->bandwidth = IMIN(st->bandwidth, IMAX(OPUS_BANDWIDTH_WIDEBAND, st->detected_bandwidth));
+          min_detected_bandwidth = OPUS_BANDWIDTH_FULLBAND;
+
+       st->detected_bandwidth = IMAX(st->detected_bandwidth, min_detected_bandwidth);
+       st->bandwidth = IMIN(st->bandwidth, st->detected_bandwidth);
     }
 #endif
     celt_encoder_ctl(celt_enc, OPUS_SET_LSB_DEPTH(lsb_depth));