shithub: opus

Download patch

ref: 955f94c21ae29677b0f3ad3a923232cfb37d74b3
parent: a3ef43818d7c8aec4fce4b787ae86f1104d12f0e
author: Jean-Marc Valin <[email protected]>
date: Tue Mar 8 17:12:43 EST 2011

Automatic bandwidth selection

--- a/src/opus.h
+++ b/src/opus.h
@@ -71,11 +71,12 @@
 #define MODE_HYBRID    1001
 #define MODE_CELT_ONLY 1002
 
-#define BANDWIDTH_NARROWBAND    1100
-#define BANDWIDTH_MEDIUMBAND    1101
-#define BANDWIDTH_WIDEBAND      1102
-#define BANDWIDTH_SUPERWIDEBAND 1103
-#define BANDWIDTH_FULLBAND      1104
+#define BANDWIDTH_AUTO          1100
+#define BANDWIDTH_NARROWBAND    1101
+#define BANDWIDTH_MEDIUMBAND    1102
+#define BANDWIDTH_WIDEBAND      1103
+#define BANDWIDTH_SUPERWIDEBAND 1104
+#define BANDWIDTH_FULLBAND      1105
 
 
 
@@ -135,7 +136,7 @@
 
 void opus_encoder_destroy(OpusEncoder *st);
 
-void opus_encoder_ctl(OpusEncoder *st, int request, ...);
+int opus_encoder_ctl(OpusEncoder *st, int request, ...);
 
 OpusDecoder *opus_decoder_create(int Fs, int channels);
 
@@ -143,7 +144,7 @@
 int opus_decode(OpusDecoder *st, const unsigned char *data, int len,
 		short *pcm, int frame_size, int decode_fec);
 
-void opus_decoder_ctl(OpusDecoder *st, int request, ...);
+int opus_decoder_ctl(OpusDecoder *st, int request, ...);
 
 void opus_decoder_destroy(OpusDecoder *st);
 
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -325,7 +325,7 @@
 
 }
 
-void opus_decoder_ctl(OpusDecoder *st, int request, ...)
+int opus_decoder_ctl(OpusDecoder *st, int request, ...)
 {
     va_list ap;
 
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -82,6 +82,7 @@
 	st->use_vbr = 0;
 	st->bitrate_bps = 32000;
 	st->user_mode = OPUS_MODE_AUTO;
+	st->user_bandwidth = BANDWIDTH_AUTO;
 	st->voice_ratio = 90;
 
 	st->encoder_buffer = st->Fs/100;
@@ -178,6 +179,19 @@
         else
             st->bandwidth = BANDWIDTH_NARROWBAND;
     }
+
+    if (st->Fs <= 24000 && st->bandwidth > BANDWIDTH_SUPERWIDEBAND)
+    	st->bandwidth = BANDWIDTH_SUPERWIDEBAND;
+    if (st->Fs <= 16000 && st->bandwidth > BANDWIDTH_WIDEBAND)
+    	st->bandwidth = BANDWIDTH_WIDEBAND;
+    if (st->Fs <= 12000 && st->bandwidth > BANDWIDTH_MEDIUMBAND)
+    	st->bandwidth = BANDWIDTH_MEDIUMBAND;
+    if (st->Fs <= 8000 && st->bandwidth > BANDWIDTH_NARROWBAND)
+    	st->bandwidth = BANDWIDTH_NARROWBAND;
+
+    if (st->user_bandwidth != BANDWIDTH_AUTO)
+    	st->bandwidth = st->user_bandwidth;
+
     /* Preventing non-sensical configurations */
     if (frame_size < st->Fs/100 && st->mode != MODE_CELT_ONLY)
         st->mode = MODE_CELT_ONLY;
@@ -471,7 +485,7 @@
     return ret+1+redundancy_bytes;
 }
 
-void opus_encoder_ctl(OpusEncoder *st, int request, ...)
+int opus_encoder_ctl(OpusEncoder *st, int request, ...)
 {
     va_list ap;
 
@@ -488,7 +502,7 @@
         case OPUS_GET_MODE_REQUEST:
         {
             int *value = va_arg(ap, int*);
-            *value = st->user_mode;
+            *value = st->mode;
         }
         break;
         case OPUS_SET_BITRATE_REQUEST:
@@ -506,8 +520,10 @@
         case OPUS_SET_BANDWIDTH_REQUEST:
         {
             int value = va_arg(ap, int);
-            st->bandwidth = value;
-            if (st->bandwidth == BANDWIDTH_NARROWBAND) {
+            if (value < BANDWIDTH_AUTO || value > BANDWIDTH_FULLBAND)
+            	return OPUS_BAD_ARG;
+            st->user_bandwidth = value;
+            if (st->user_bandwidth == BANDWIDTH_NARROWBAND) {
                 st->silk_mode.maxInternalSampleRate = 8000;
             } else if (st->bandwidth == BANDWIDTH_MEDIUMBAND) {
                 st->silk_mode.maxInternalSampleRate = 12000;
--- a/src/opus_encoder.h
+++ b/src/opus_encoder.h
@@ -46,6 +46,7 @@
     int          user_mode;
     int          prev_mode;
 	int          bandwidth;
+	int          user_bandwidth;
 	int          voice_ratio;
     /* Sampling rate (at the API level) */
     int          Fs;
--- a/src/test_opus.c
+++ b/src/test_opus.c
@@ -112,7 +112,7 @@
 
    /* defaults: */
    use_vbr = 1;
-   bandwidth=-1;
+   bandwidth=BANDWIDTH_AUTO;
    internal_sampling_rate_Hz = sampling_rate;
    max_payload_bytes = MAX_PACKET;
    complexity = 10;
@@ -120,24 +120,6 @@
    use_dtx = 0;
    packet_loss_perc = 0;
 
-   switch(sampling_rate)
-   {
-   case 8000:
-	   bandwidth = BANDWIDTH_NARROWBAND;
-	   break;
-   case 12000:
-	   bandwidth = BANDWIDTH_MEDIUMBAND;
-	   break;
-   case 16000:
-	   bandwidth = BANDWIDTH_WIDEBAND;
-	   break;
-   case 24000:
-	   bandwidth = BANDWIDTH_SUPERWIDEBAND;
-	   break;
-   case 48000:
-	   bandwidth = BANDWIDTH_FULLBAND;
-	   break;
-   }
    args = 5;
    while( args < argc - 2 ) {
        /* process command line options */
@@ -236,11 +218,6 @@
    enc = opus_encoder_create(sampling_rate, channels);
    dec = opus_decoder_create(sampling_rate, channels);
 
-   if (bandwidth == -1)
-   {
-       fprintf (stderr, "Please specify a bandwidth when the sampling rate does not match one exactly\n");
-       return 1;
-   }
    opus_encoder_ctl(enc, OPUS_SET_MODE(mode));
    opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
    opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bandwidth));
@@ -271,6 +248,9 @@
 	   break;
    case BANDWIDTH_FULLBAND:
 	   bandwidth_string = "fullband";
+	   break;
+   case BANDWIDTH_AUTO:
+	   bandwidth_string = "auto";
 	   break;
    default:
 	   bandwidth_string = "unknown";