From 07dceb72dee0a1332b4f0e631d4089f687e58dc0 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin <jmvalin@jmvalin.ca> Date: Thu, 8 Sep 2011 13:53:20 -0400 Subject: [PATCH] Adds ctl() requests for forcing any operating mode in the encoder Also merges all the OPUS_*_AUTO into a single OPUS_AUTO parameter --- libcelt/opus_defines.h | 15 +++++++------ src/opus_encoder.c | 48 +++++++++++++++++++++++++++--------------- src/opus_private.h | 4 ++++ src/test_opus.c | 12 +++++------ 4 files changed, 49 insertions(+), 30 deletions(-) diff --git a/libcelt/opus_defines.h b/libcelt/opus_defines.h index 6580dc21a..ac1c46626 100644 --- a/libcelt/opus_defines.h +++ b/libcelt/opus_defines.h @@ -85,8 +85,8 @@ extern "C" { #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 @@ extern "C" { */ /** \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 @@ extern "C" { * 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: diff --git a/src/opus_encoder.c b/src/opus_encoder.c index 1aaeb65df..e5a94754d 100644 --- a/src/opus_encoder.c +++ b/src/opus_encoder.c @@ -57,9 +57,10 @@ struct OpusEncoder { 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 @@ int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int applicat 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 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, 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 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, 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 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, } #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 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, 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 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, 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 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, 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 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, 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 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) 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 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) *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) { @@ -1140,6 +1146,14 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...) 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: /* fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);*/ ret = OPUS_UNIMPLEMENTED; diff --git a/src/opus_private.h b/src/opus_private.h index 198fdf2b6..fd1310ce6 100644 --- 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, diff --git a/src/test_opus.c b/src/test_opus.c index d6bf46254..cd5975824 100644 --- a/src/test_opus.c +++ b/src/test_opus.c @@ -98,7 +98,7 @@ int main(int argc, char *argv[]) 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 @@ int main(int argc, char *argv[]) /* 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 @@ int main(int argc, char *argv[]) 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 @@ int main(int argc, char *argv[]) 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 @@ int main(int argc, char *argv[]) case OPUS_BANDWIDTH_FULLBAND: bandwidth_string = "fullband"; break; - case OPUS_BANDWIDTH_AUTO: + case OPUS_AUTO: bandwidth_string = "auto"; break; default: -- GitLab