ref: 07dceb72dee0a1332b4f0e631d4089f687e58dc0
parent: 75ff53c70e7e2b8781dadd21a84be3056e1cde69
author: Jean-Marc Valin <[email protected]>
date: Thu Sep 8 09:53:20 EDT 2011
Adds ctl() requests for forcing any operating mode in the encoder Also merges all the OPUS_*_AUTO into a single OPUS_AUTO parameter
--- a/libcelt/opus_defines.h
+++ b/libcelt/opus_defines.h
@@ -85,8 +85,8 @@
#define OPUS_GET_VBR_REQUEST 4007
#define OPUS_SET_VBR_CONSTRAINT_REQUEST 4020
#define OPUS_GET_VBR_CONSTRAINT_REQUEST 4021
-#define OPUS_SET_FORCE_MONO_REQUEST 4022
-#define OPUS_GET_FORCE_MONO_REQUEST 4023
+#define OPUS_SET_FORCE_CHANNELS_REQUEST 4022
+#define OPUS_GET_FORCE_CHANNELS_REQUEST 4023
#define OPUS_SET_BANDWIDTH_REQUEST 4008
#define OPUS_GET_BANDWIDTH_REQUEST 4009
#define OPUS_SET_SIGNAL_REQUEST 4024
@@ -116,14 +116,15 @@
*/
/** \cond DOXYGEN_EXCLUDE */
/* Values for the varrious encoder CTLs */
-#define OPUS_BITRATE_AUTO -2 /**<Auto bitrate @hideinitializer*/
+#define OPUS_AUTO -1000 /**<Auto bitrate @hideinitializer*/
+//#define OPUS_BITRATE_AUTO -2 /**<Auto bitrate @hideinitializer*/
#define OPUS_BITRATE_MAX -1 /**<Maximum bitrate @hideinitializer*/
#define OPUS_APPLICATION_VOIP 2000
#define OPUS_APPLICATION_AUDIO 2001
-#define OPUS_SIGNAL_AUTO 3000
+//#define OPUS_SIGNAL_AUTO 3000
#define OPUS_SIGNAL_VOICE 3001
#define OPUS_SIGNAL_MUSIC 3002
-#define OPUS_BANDWIDTH_AUTO 1100 /**<Automatic bandpass @hideinitializer*/
+//#define OPUS_BANDWIDTH_AUTO 1100 /**<Automatic bandpass @hideinitializer*/
#define OPUS_BANDWIDTH_NARROWBAND 1101 /**< 4kHz bandpass @hideinitializer*/
#define OPUS_BANDWIDTH_MEDIUMBAND 1102 /**< 6kHz bandpass @hideinitializer*/
#define OPUS_BANDWIDTH_WIDEBAND 1103 /**< 8kHz bandpass @hideinitializer*/
@@ -194,11 +195,11 @@
* source embedded in a stereo stream.
* \param[in] x <tt>int</tt>: 0 (default); 1 (forced mono)
* @hideinitializer */
-#define OPUS_SET_FORCE_MONO(x) OPUS_SET_FORCE_MONO_REQUEST, __opus_check_int(x)
+#define OPUS_SET_FORCE_CHANNELS(x) OPUS_SET_FORCE_CHANNELS_REQUEST, __opus_check_int(x)
/** Gets the encoder's forced mono configuration, @see [OPUS_SET_FORCE_MONO]
* \param[out] x <tt>int*</tt>: 0; 1
* @hideinitializer */
-#define OPUS_GET_FORCE_MONO(x) OPUS_GET_FORCE_MONO_REQUEST, __opus_check_int_ptr(x)
+#define OPUS_GET_FORCE_CHANNELS(x) OPUS_GET_FORCE_CHANNELS_REQUEST, __opus_check_int_ptr(x)
/** Configures the encoder's bandpass.
* The supported values are:
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -57,9 +57,10 @@
int application;
int channels;
int delay_compensation;
- int force_mono;
+ int force_channels;
int signal_type;
int user_bandwidth;
+ int user_forced_mode;
int voice_ratio;
opus_int32 Fs;
int use_vbr;
@@ -189,11 +190,13 @@
celt_encoder_ctl(celt_enc, CELT_SET_SIGNALLING(0));
st->use_vbr = 0;
- st->user_bitrate_bps = OPUS_BITRATE_AUTO;
+ st->user_bitrate_bps = OPUS_AUTO;
st->bitrate_bps = 3000+Fs*channels;
st->application = application;
- st->signal_type = OPUS_SIGNAL_AUTO;
- st->user_bandwidth = OPUS_BANDWIDTH_AUTO;
+ st->signal_type = OPUS_AUTO;
+ st->user_bandwidth = OPUS_AUTO;
+ st->force_channels = OPUS_AUTO;
+ st->user_forced_mode = OPUS_AUTO;
st->voice_ratio = -1;
st->encoder_buffer = st->Fs/100;
@@ -383,7 +386,7 @@
silk_enc = (char*)st+st->silk_enc_offset;
celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);
- if (st->user_bitrate_bps==OPUS_BITRATE_AUTO)
+ if (st->user_bitrate_bps==OPUS_AUTO)
st->bitrate_bps = 60*st->Fs/frame_size + st->Fs*st->channels;
else if (st->user_bitrate_bps==OPUS_BITRATE_MAX)
st->bitrate_bps = max_data_bytes*8*st->Fs/frame_size;
@@ -410,9 +413,9 @@
st->stream_channels = 3-st->stream_channels;
#else
/* Rate-dependent mono-stereo decision */
- if (st->force_mono)
+ if (st->force_channels!=OPUS_AUTO && st->channels == 2)
{
- st->stream_channels = 1;
+ st->stream_channels = st->force_channels;
} else if (st->channels == 2)
{
opus_int32 stereo_threshold;
@@ -443,12 +446,13 @@
}
#else
/* Mode selection depending on application and signal type */
+ if (st->user_forced_mode == OPUS_AUTO)
{
int chan;
opus_int32 mode_voice, mode_music;
opus_int32 threshold;
- chan = (st->channels==2) && !st->force_mono;
+ chan = (st->channels==2) && st->force_channels!=1;
mode_voice = mode_thresholds[chan][0];
mode_music = mode_thresholds[chan][1];
threshold = mode_music + ((voice_est*voice_est*(mode_voice-mode_music))>>14);
@@ -460,6 +464,8 @@
threshold += 4000;
st->mode = (equiv_rate >= threshold) ? MODE_CELT_ONLY: MODE_SILK_ONLY;
+ } else {
+ st->mode = st->user_forced_mode;
}
#endif
@@ -501,7 +507,7 @@
opus_int32 bandwidth_thresholds[8];
int bandwidth = OPUS_BANDWIDTH_FULLBAND;
- if (st->channels==2 && !st->force_mono)
+ if (st->channels==2 && st->force_channels!=1)
{
voice_bandwidth_thresholds = stereo_voice_bandwidth_thresholds;
music_bandwidth_thresholds = stereo_music_bandwidth_thresholds;
@@ -547,7 +553,7 @@
if (st->Fs <= 8000 && st->bandwidth > OPUS_BANDWIDTH_NARROWBAND)
st->bandwidth = OPUS_BANDWIDTH_NARROWBAND;
- if (st->user_bandwidth != OPUS_BANDWIDTH_AUTO)
+ if (st->user_bandwidth != OPUS_AUTO)
st->bandwidth = st->user_bandwidth;
/* Can't support higher than wideband for >20 ms frames */
@@ -559,7 +565,7 @@
st->bandwidth = OPUS_BANDWIDTH_WIDEBAND;
/* Chooses the appropriate mode for speech
- *NEVER* switch to/from CELT-only mode here as this will */
+ *NEVER* switch to/from CELT-only mode here as this will invalidate some assumptions */
if (st->mode == MODE_SILK_ONLY && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND)
st->mode = MODE_HYBRID;
if (st->mode == MODE_HYBRID && st->bandwidth <= OPUS_BANDWIDTH_WIDEBAND)
@@ -954,7 +960,7 @@
case OPUS_SET_BITRATE_REQUEST:
{
opus_int32 value = va_arg(ap, opus_int32);
- if (value != OPUS_BITRATE_AUTO && value != OPUS_BITRATE_MAX)
+ if (value != OPUS_AUTO && value != OPUS_BITRATE_MAX)
{
if (value <= 0)
goto bad_arg;
@@ -972,22 +978,22 @@
*value = st->bitrate_bps;
}
break;
- case OPUS_SET_FORCE_MONO_REQUEST:
+ case OPUS_SET_FORCE_CHANNELS_REQUEST:
{
opus_int32 value = va_arg(ap, opus_int32);
- st->force_mono = value;
+ st->force_channels = value;
}
break;
- case OPUS_GET_FORCE_MONO_REQUEST:
+ case OPUS_GET_FORCE_CHANNELS_REQUEST:
{
opus_int32 *value = va_arg(ap, opus_int32*);
- *value = !!st->force_mono;
+ *value = st->force_channels;
}
break;
case OPUS_SET_BANDWIDTH_REQUEST:
{
opus_int32 value = va_arg(ap, opus_int32);
- if (value < OPUS_BANDWIDTH_AUTO || value > OPUS_BANDWIDTH_FULLBAND)
+ if ((value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND) && value != OPUS_AUTO)
return OPUS_BAD_ARG;
st->user_bandwidth = value;
if (st->user_bandwidth == OPUS_BANDWIDTH_NARROWBAND) {
@@ -1138,6 +1144,14 @@
st->mode = MODE_HYBRID;
st->bandwidth = OPUS_BANDWIDTH_FULLBAND;
st->variable_HP_smth2_Q15 = SKP_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );
+ }
+ break;
+ case OPUS_SET_FORCE_MODE_REQUEST:
+ {
+ opus_int32 value = va_arg(ap, opus_int32);
+ if (value < MODE_SILK_ONLY || value > MODE_CELT_ONLY)
+ goto bad_arg;
+ st->user_forced_mode = value;
}
break;
default:
--- a/src/opus_private.h
+++ b/src/opus_private.h
@@ -36,6 +36,10 @@
#define MODE_HYBRID 1001
#define MODE_CELT_ONLY 1002
+#define OPUS_SET_FORCE_MODE_REQUEST 11002
+#define OPUS_SET_FORCE_MODE(x) OPUS_SET_FORCE_MODE_REQUEST, __opus_check_int(x)
+
+
int encode_size(int size, unsigned char *data);
int opus_decode_native(OpusDecoder *st, const unsigned char *data, int len,
--- a/src/test_opus.c
+++ b/src/test_opus.c
@@ -98,7 +98,7 @@
int complexity;
int use_inbandfec;
int use_dtx;
- int forcemono;
+ int forcechannels;
int cvbr = 0;
int packet_loss_perc;
opus_int32 count=0, count_act=0;
@@ -154,11 +154,11 @@
/* defaults: */
use_vbr = 1;
- bandwidth = OPUS_BANDWIDTH_AUTO;
+ bandwidth = OPUS_AUTO;
max_payload_bytes = MAX_PACKET;
complexity = 10;
use_inbandfec = 0;
- forcemono = 0;
+ forcechannels = OPUS_AUTO;
use_dtx = 0;
packet_loss_perc = 0;
max_frame_size = 960*6;
@@ -214,7 +214,7 @@
use_inbandfec = 1;
args++;
} else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-forcemono" ) == 0 ) {
- forcemono = 1;
+ forcechannels = 1;
args++;
} else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-cvbr" ) == 0 ) {
cvbr = 1;
@@ -292,7 +292,7 @@
opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(cvbr));
opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity));
opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(use_inbandfec));
- opus_encoder_ctl(enc, OPUS_SET_FORCE_MONO(forcemono));
+ opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(forcechannels));
opus_encoder_ctl(enc, OPUS_SET_DTX(use_dtx));
opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packet_loss_perc));
@@ -318,7 +318,7 @@
case OPUS_BANDWIDTH_FULLBAND:
bandwidth_string = "fullband";
break;
- case OPUS_BANDWIDTH_AUTO:
+ case OPUS_AUTO:
bandwidth_string = "auto";
break;
default: