shithub: opus

Download patch

ref: 09c67660129f91f9a11e68589b5e96af290cbf5f
parent: 85c599f93c8e739b3d771570bc80e2cd83b1a431
author: Jean-Marc Valin <[email protected]>
date: Wed May 4 18:34:53 EDT 2011

Rewrote the bandwidth selection code

New code should be cleaner and easier to tune

--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -38,6 +38,22 @@
 #include "modes.h"
 #include "SKP_Silk_SDK_API.h"
 
+/* Transition table for the voice mode */
+static const int voice_bandwidth_thresholds[10] = {
+		11500, 1500, /* NB<->MB */
+		14500, 1500, /* MB<->WB */
+		21000, 2000, /* WB<->SWB */
+		29000, 2000, /* SWB<->FB */
+};
+/* Transition table for the audio mode */
+static const int audio_bandwidth_thresholds[10] = {
+		30000,    0, /* MB not allowed */
+		20000, 2000, /* MB<->WB */
+		26000, 2000, /* WB<->SWB */
+		33000, 2000, /* SWB<->FB */
+};
+
+
 OpusEncoder *opus_encoder_create(int Fs, int channels)
 {
     int err;
@@ -166,31 +182,30 @@
     }
 
     /* Automatic (rate-dependent) bandwidth selection */
-    if (st->mode == MODE_CELT_ONLY)
+    if (st->mode == MODE_CELT_ONLY || st->first || st->silk_mode.allowBandwidthSwitch)
     {
-    	if (mono_rate>35000 || (mono_rate>28000 && st->bandwidth==BANDWIDTH_FULLBAND))
-    		st->bandwidth = BANDWIDTH_FULLBAND;
-    	else if (mono_rate>28000 || (mono_rate>24000 && st->bandwidth>=BANDWIDTH_SUPERWIDEBAND))
-    		st->bandwidth = BANDWIDTH_SUPERWIDEBAND;
-    	else if (mono_rate>24000 || (mono_rate>18000 && st->bandwidth>=BANDWIDTH_WIDEBAND))
-    		st->bandwidth = BANDWIDTH_WIDEBAND;
-    	else
-    		st->bandwidth = BANDWIDTH_NARROWBAND;
-    } else if (st->first || st->silk_mode.allowBandwidthSwitch)
-    {
-    	if (mono_rate>31000 || (mono_rate>27000 && st->bandwidth==BANDWIDTH_FULLBAND))
-    		st->bandwidth = BANDWIDTH_FULLBAND;
-    	else if (mono_rate>23000 || (mono_rate>19000 && st->bandwidth>=BANDWIDTH_SUPERWIDEBAND))
-    		st->bandwidth = BANDWIDTH_SUPERWIDEBAND;
-    	else if (mono_rate>16000 || (mono_rate>13000 && st->bandwidth>=BANDWIDTH_WIDEBAND))
-    		st->bandwidth = BANDWIDTH_WIDEBAND;
-    	else if (mono_rate>13000 || (mono_rate>10000 && st->bandwidth>=BANDWIDTH_MEDIUMBAND))
-    		st->bandwidth = BANDWIDTH_MEDIUMBAND;
-    	else
-    		st->bandwidth = BANDWIDTH_NARROWBAND;
+    	const int *bandwidth_thresholds;
+    	int bandwidth = BANDWIDTH_FULLBAND;
+
+    	bandwidth_thresholds = st->mode == MODE_CELT_ONLY ? audio_bandwidth_thresholds : voice_bandwidth_thresholds;
+    	do {
+    		int threshold, hysteresis;
+    		threshold = bandwidth_thresholds[2*(bandwidth-BANDWIDTH_MEDIUMBAND)];
+    		hysteresis = bandwidth_thresholds[2*(bandwidth-BANDWIDTH_MEDIUMBAND)+1];
+    		if (!st->first)
+    		{
+    			if (st->bandwidth >= bandwidth)
+    				threshold -= hysteresis;
+    			else
+    				threshold += hysteresis;
+    		}
+    		if (mono_rate >= threshold)
+    			break;
+    	} while (--bandwidth>BANDWIDTH_NARROWBAND);
+    	st->bandwidth = bandwidth;
     	/* Prevents any transition to SWB/FB until the SILK layer has fully
     	   switched to WB mode and turned the variable LP filter off */
-    	if (!st->silk_mode.inWBmodeWithoutVariableLP && st->bandwidth > BANDWIDTH_WIDEBAND)
+    	if (st->mode != MODE_CELT_ONLY && !st->silk_mode.inWBmodeWithoutVariableLP && st->bandwidth > BANDWIDTH_WIDEBAND)
     		st->bandwidth = BANDWIDTH_WIDEBAND;
     }