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";