Adds OPUS_SET_RESTRICTED_LOWDELAY() encoder ctl
Right now it will uncleanly switch to SILK if asked for 40 or 60 ms frames
This commit is contained in:
parent
07dceb72de
commit
d186c913f7
3 changed files with 66 additions and 23 deletions
|
@ -103,6 +103,8 @@ extern "C" {
|
||||||
#define OPUS_SET_DTX_REQUEST 4016
|
#define OPUS_SET_DTX_REQUEST 4016
|
||||||
#define OPUS_GET_DTX_REQUEST 4017
|
#define OPUS_GET_DTX_REQUEST 4017
|
||||||
#define OPUS_GET_FINAL_RANGE_REQUEST 4031
|
#define OPUS_GET_FINAL_RANGE_REQUEST 4031
|
||||||
|
#define OPUS_SET_RESTRICTED_LOWDELAY_REQUEST 4032
|
||||||
|
#define OPUS_GET_RESTRICTED_LOWDELAY_REQUEST 4033
|
||||||
|
|
||||||
/* Macros to trigger compilation errors when the wrong types are provided to a CTL */
|
/* Macros to trigger compilation errors when the wrong types are provided to a CTL */
|
||||||
#define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x))
|
#define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x))
|
||||||
|
@ -117,14 +119,11 @@ extern "C" {
|
||||||
/** \cond DOXYGEN_EXCLUDE */
|
/** \cond DOXYGEN_EXCLUDE */
|
||||||
/* Values for the varrious encoder CTLs */
|
/* Values for the varrious encoder CTLs */
|
||||||
#define OPUS_AUTO -1000 /**<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_BITRATE_MAX -1 /**<Maximum bitrate @hideinitializer*/
|
||||||
#define OPUS_APPLICATION_VOIP 2000
|
#define OPUS_APPLICATION_VOIP 2000
|
||||||
#define OPUS_APPLICATION_AUDIO 2001
|
#define OPUS_APPLICATION_AUDIO 2001
|
||||||
//#define OPUS_SIGNAL_AUTO 3000
|
|
||||||
#define OPUS_SIGNAL_VOICE 3001
|
#define OPUS_SIGNAL_VOICE 3001
|
||||||
#define OPUS_SIGNAL_MUSIC 3002
|
#define OPUS_SIGNAL_MUSIC 3002
|
||||||
//#define OPUS_BANDWIDTH_AUTO 1100 /**<Automatic bandpass @hideinitializer*/
|
|
||||||
#define OPUS_BANDWIDTH_NARROWBAND 1101 /**< 4kHz bandpass @hideinitializer*/
|
#define OPUS_BANDWIDTH_NARROWBAND 1101 /**< 4kHz bandpass @hideinitializer*/
|
||||||
#define OPUS_BANDWIDTH_MEDIUMBAND 1102 /**< 6kHz bandpass @hideinitializer*/
|
#define OPUS_BANDWIDTH_MEDIUMBAND 1102 /**< 6kHz bandpass @hideinitializer*/
|
||||||
#define OPUS_BANDWIDTH_WIDEBAND 1103 /**< 8kHz bandpass @hideinitializer*/
|
#define OPUS_BANDWIDTH_WIDEBAND 1103 /**< 8kHz bandpass @hideinitializer*/
|
||||||
|
@ -190,14 +189,14 @@ extern "C" {
|
||||||
* @hideinitializer */
|
* @hideinitializer */
|
||||||
#define OPUS_GET_VBR_CONSTRAINT(x) OPUS_GET_VBR_CONSTRAINT_REQUEST, __opus_check_int_ptr(x)
|
#define OPUS_GET_VBR_CONSTRAINT(x) OPUS_GET_VBR_CONSTRAINT_REQUEST, __opus_check_int_ptr(x)
|
||||||
|
|
||||||
/** Configures mono forcing in the encoder.
|
/** Configures mono/stereo forcing in the encoder.
|
||||||
* This is useful when the caller knows that the input signal is currently a mono
|
* This is useful when the caller knows that the input signal is currently a mono
|
||||||
* source embedded in a stereo stream.
|
* source embedded in a stereo stream.
|
||||||
* \param[in] x <tt>int</tt>: 0 (default); 1 (forced mono)
|
* \param[in] x <tt>int</tt>: OPUS_AUTO (default); 1 (forced mono); 2 (forced stereo)
|
||||||
* @hideinitializer */
|
* @hideinitializer */
|
||||||
#define OPUS_SET_FORCE_CHANNELS(x) OPUS_SET_FORCE_CHANNELS_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]
|
/** Gets the encoder's forced channel configuration, @see [OPUS_SET_FORCE_CHANNELS]
|
||||||
* \param[out] x <tt>int*</tt>: 0; 1
|
* \param[out] x <tt>int*</tt>: OPUS_AUTO; 0; 1
|
||||||
* @hideinitializer */
|
* @hideinitializer */
|
||||||
#define OPUS_GET_FORCE_CHANNELS(x) OPUS_GET_FORCE_CHANNELS_REQUEST, __opus_check_int_ptr(x)
|
#define OPUS_GET_FORCE_CHANNELS(x) OPUS_GET_FORCE_CHANNELS_REQUEST, __opus_check_int_ptr(x)
|
||||||
|
|
||||||
|
@ -337,6 +336,19 @@ extern "C" {
|
||||||
*
|
*
|
||||||
* @hideinitializer */
|
* @hideinitializer */
|
||||||
#define OPUS_GET_FINAL_RANGE(x) OPUS_GET_FINAL_RANGE_REQUEST, __opus_check_uint_ptr(x)
|
#define OPUS_GET_FINAL_RANGE(x) OPUS_GET_FINAL_RANGE_REQUEST, __opus_check_uint_ptr(x)
|
||||||
|
|
||||||
|
/** Configures low-delay mode that disables the speech-optimized mode in exchange for slightly reduced delay.
|
||||||
|
* This is useful when the caller knows that the speech-optimized modes will not be needed (use with caution).
|
||||||
|
* The setting can only be changed right after initialization or after a reset.
|
||||||
|
* \param[in] x <tt>int</tt>: 0 (default); 1 (lowdelay)
|
||||||
|
* @hideinitializer */
|
||||||
|
#define OPUS_SET_RESTRICTED_LOWDELAY(x) OPUS_SET_RESTRICTED_LOWDELAY_REQUEST, __opus_check_int(x)
|
||||||
|
/** Gets the encoder's forced channel configuration, @see [OPUS_SET_RESTRICTED_LOWDELAY]
|
||||||
|
* \param[out] x <tt>int*</tt>: 0; 1
|
||||||
|
* @hideinitializer */
|
||||||
|
#define OPUS_GET_RESTRICTED_LOWDELAY(x) OPUS_GET_RESTRICTED_LOWDELAY_REQUEST, __opus_check_int_ptr(x)
|
||||||
|
|
||||||
|
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
/** \defgroup libinfo Opus library information functions
|
/** \defgroup libinfo Opus library information functions
|
||||||
|
|
|
@ -67,6 +67,7 @@ struct OpusEncoder {
|
||||||
int vbr_constraint;
|
int vbr_constraint;
|
||||||
int bitrate_bps;
|
int bitrate_bps;
|
||||||
int user_bitrate_bps;
|
int user_bitrate_bps;
|
||||||
|
int lowdelay;
|
||||||
int encoder_buffer;
|
int encoder_buffer;
|
||||||
|
|
||||||
#define OPUS_ENCODER_RESET_START stream_channels
|
#define OPUS_ENCODER_RESET_START stream_channels
|
||||||
|
@ -374,6 +375,7 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
|
||||||
int cutoff_Hz, hp_freq_smth1;
|
int cutoff_Hz, hp_freq_smth1;
|
||||||
int voice_est;
|
int voice_est;
|
||||||
opus_int32 equiv_rate;
|
opus_int32 equiv_rate;
|
||||||
|
int delay_compensation;
|
||||||
ALLOC_STACK;
|
ALLOC_STACK;
|
||||||
|
|
||||||
st->rangeFinal = 0;
|
st->rangeFinal = 0;
|
||||||
|
@ -386,6 +388,11 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
|
||||||
silk_enc = (char*)st+st->silk_enc_offset;
|
silk_enc = (char*)st+st->silk_enc_offset;
|
||||||
celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);
|
celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);
|
||||||
|
|
||||||
|
if (st->lowdelay)
|
||||||
|
delay_compensation = 0;
|
||||||
|
else
|
||||||
|
delay_compensation = st->delay_compensation;
|
||||||
|
|
||||||
if (st->user_bitrate_bps==OPUS_AUTO)
|
if (st->user_bitrate_bps==OPUS_AUTO)
|
||||||
st->bitrate_bps = 60*st->Fs/frame_size + st->Fs*st->channels;
|
st->bitrate_bps = 60*st->Fs/frame_size + st->Fs*st->channels;
|
||||||
else if (st->user_bitrate_bps==OPUS_BITRATE_MAX)
|
else if (st->user_bitrate_bps==OPUS_BITRATE_MAX)
|
||||||
|
@ -446,7 +453,10 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* Mode selection depending on application and signal type */
|
/* Mode selection depending on application and signal type */
|
||||||
if (st->user_forced_mode == OPUS_AUTO)
|
if (st->lowdelay)
|
||||||
|
{
|
||||||
|
st->mode = MODE_CELT_ONLY;
|
||||||
|
} else if (st->user_forced_mode == OPUS_AUTO)
|
||||||
{
|
{
|
||||||
int chan;
|
int chan;
|
||||||
opus_int32 mode_voice, mode_music;
|
opus_int32 mode_voice, mode_music;
|
||||||
|
@ -578,9 +588,9 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
|
||||||
|
|
||||||
ec_enc_init(&enc, data, max_data_bytes-1);
|
ec_enc_init(&enc, data, max_data_bytes-1);
|
||||||
|
|
||||||
ALLOC(pcm_buf, (st->delay_compensation+frame_size)*st->channels, opus_val16);
|
ALLOC(pcm_buf, (delay_compensation+frame_size)*st->channels, opus_val16);
|
||||||
for (i=0;i<st->delay_compensation*st->channels;i++)
|
for (i=0;i<delay_compensation*st->channels;i++)
|
||||||
pcm_buf[i] = st->delay_buffer[(st->encoder_buffer-st->delay_compensation)*st->channels+i];
|
pcm_buf[i] = st->delay_buffer[(st->encoder_buffer-delay_compensation)*st->channels+i];
|
||||||
|
|
||||||
if (st->mode == MODE_CELT_ONLY)
|
if (st->mode == MODE_CELT_ONLY)
|
||||||
hp_freq_smth1 = SKP_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );
|
hp_freq_smth1 = SKP_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );
|
||||||
|
@ -595,10 +605,10 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
|
||||||
|
|
||||||
if (st->application == OPUS_APPLICATION_VOIP)
|
if (st->application == OPUS_APPLICATION_VOIP)
|
||||||
{
|
{
|
||||||
hp_cutoff(pcm, cutoff_Hz, &pcm_buf[st->delay_compensation*st->channels], st->hp_mem, frame_size, st->channels, st->Fs);
|
hp_cutoff(pcm, cutoff_Hz, &pcm_buf[delay_compensation*st->channels], st->hp_mem, frame_size, st->channels, st->Fs);
|
||||||
} else {
|
} else {
|
||||||
for (i=0;i<frame_size*st->channels;i++)
|
for (i=0;i<frame_size*st->channels;i++)
|
||||||
pcm_buf[st->delay_compensation*st->channels + i] = pcm[i];
|
pcm_buf[delay_compensation*st->channels + i] = pcm[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SILK processing */
|
/* SILK processing */
|
||||||
|
@ -671,10 +681,10 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
pcm_silk = pcm_buf+st->delay_compensation*st->channels;
|
pcm_silk = pcm_buf+delay_compensation*st->channels;
|
||||||
#else
|
#else
|
||||||
for (i=0;i<frame_size*st->channels;i++)
|
for (i=0;i<frame_size*st->channels;i++)
|
||||||
pcm_silk[i] = FLOAT2INT16(pcm_buf[st->delay_compensation*st->channels + i]);
|
pcm_silk[i] = FLOAT2INT16(pcm_buf[delay_compensation*st->channels + i]);
|
||||||
#endif
|
#endif
|
||||||
ret = silk_Encode( silk_enc, &st->silk_mode, pcm_silk, frame_size, &enc, &nBytes, 0 );
|
ret = silk_Encode( silk_enc, &st->silk_mode, pcm_silk, frame_size, &enc, &nBytes, 0 );
|
||||||
if( ret ) {
|
if( ret ) {
|
||||||
|
@ -736,7 +746,7 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
|
||||||
celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
|
celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
|
||||||
celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
|
celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
|
||||||
/* TODO: This wastes CPU a bit compared to just prefilling the buffer */
|
/* TODO: This wastes CPU a bit compared to just prefilling the buffer */
|
||||||
celt_encode_with_ec(celt_enc, &st->delay_buffer[(st->encoder_buffer-st->delay_compensation-st->Fs/400)*st->channels], st->Fs/400, dummy, 10, NULL);
|
celt_encode_with_ec(celt_enc, &st->delay_buffer[(st->encoder_buffer-delay_compensation-st->Fs/400)*st->channels], st->Fs/400, dummy, 10, NULL);
|
||||||
} else {
|
} else {
|
||||||
celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(2));
|
celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(2));
|
||||||
}
|
}
|
||||||
|
@ -768,10 +778,10 @@ int opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
|
||||||
nb_compr_bytes = 0;
|
nb_compr_bytes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0;i<st->channels*(st->encoder_buffer-(frame_size+st->delay_compensation));i++)
|
for (i=0;i<st->channels*(st->encoder_buffer-(frame_size+delay_compensation));i++)
|
||||||
st->delay_buffer[i] = st->delay_buffer[i+st->channels*frame_size];
|
st->delay_buffer[i] = st->delay_buffer[i+st->channels*frame_size];
|
||||||
for (;i<st->encoder_buffer*st->channels;i++)
|
for (;i<st->encoder_buffer*st->channels;i++)
|
||||||
st->delay_buffer[i] = pcm_buf[(frame_size+st->delay_compensation-st->encoder_buffer)*st->channels+i];
|
st->delay_buffer[i] = pcm_buf[(frame_size+delay_compensation-st->encoder_buffer)*st->channels+i];
|
||||||
|
|
||||||
|
|
||||||
if( st->mode == MODE_HYBRID && st->stream_channels == 2 ) {
|
if( st->mode == MODE_HYBRID && st->stream_channels == 2 ) {
|
||||||
|
@ -1117,7 +1127,9 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
|
||||||
case OPUS_GET_LOOKAHEAD_REQUEST:
|
case OPUS_GET_LOOKAHEAD_REQUEST:
|
||||||
{
|
{
|
||||||
opus_int32 *value = va_arg(ap, opus_int32*);
|
opus_int32 *value = va_arg(ap, opus_int32*);
|
||||||
*value = st->delay_compensation+st->Fs/400;
|
*value = st->Fs/400;
|
||||||
|
if (!st->lowdelay)
|
||||||
|
*value += st->delay_compensation;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OPUS_GET_FINAL_RANGE_REQUEST:
|
case OPUS_GET_FINAL_RANGE_REQUEST:
|
||||||
|
@ -1154,6 +1166,23 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
|
||||||
st->user_forced_mode = value;
|
st->user_forced_mode = value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case OPUS_SET_RESTRICTED_LOWDELAY_REQUEST:
|
||||||
|
{
|
||||||
|
opus_int32 value = va_arg(ap, opus_int32);
|
||||||
|
if (!st->first && st->lowdelay != !!value)
|
||||||
|
{
|
||||||
|
ret = OPUS_BAD_ARG;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
st->lowdelay = !!value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OPUS_GET_RESTRICTED_LOWDELAY_REQUEST:
|
||||||
|
{
|
||||||
|
opus_int32 *value = va_arg(ap, opus_int32*);
|
||||||
|
*value = st->lowdelay;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
/* fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);*/
|
/* fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);*/
|
||||||
ret = OPUS_UNIMPLEMENTED;
|
ret = OPUS_UNIMPLEMENTED;
|
||||||
|
|
|
@ -118,6 +118,7 @@ int main(int argc, char *argv[])
|
||||||
int max_frame_size = 960*6;
|
int max_frame_size = 960*6;
|
||||||
int curr_read=0;
|
int curr_read=0;
|
||||||
int sweep_bps = 0;
|
int sweep_bps = 0;
|
||||||
|
int lowdelay = 0;
|
||||||
|
|
||||||
if (argc < 7 )
|
if (argc < 7 )
|
||||||
{
|
{
|
||||||
|
@ -216,6 +217,9 @@ int main(int argc, char *argv[])
|
||||||
} else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-forcemono" ) == 0 ) {
|
} else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-forcemono" ) == 0 ) {
|
||||||
forcechannels = 1;
|
forcechannels = 1;
|
||||||
args++;
|
args++;
|
||||||
|
} else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-lowdelay" ) == 0 ) {
|
||||||
|
lowdelay = 1;
|
||||||
|
args++;
|
||||||
} else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-cvbr" ) == 0 ) {
|
} else if( STR_CASEINSENSITIVE_COMPARE( argv[ args ], "-cvbr" ) == 0 ) {
|
||||||
cvbr = 1;
|
cvbr = 1;
|
||||||
args++;
|
args++;
|
||||||
|
@ -295,11 +299,9 @@ int main(int argc, char *argv[])
|
||||||
opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(forcechannels));
|
opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(forcechannels));
|
||||||
opus_encoder_ctl(enc, OPUS_SET_DTX(use_dtx));
|
opus_encoder_ctl(enc, OPUS_SET_DTX(use_dtx));
|
||||||
opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packet_loss_perc));
|
opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packet_loss_perc));
|
||||||
|
opus_encoder_ctl(enc, OPUS_SET_RESTRICTED_LOWDELAY(lowdelay));
|
||||||
|
|
||||||
skip = 5*sampling_rate/1000;
|
opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&skip));
|
||||||
/* When SILK resamples, add 18 samples delay */
|
|
||||||
/*if (mode != MODE_SILK_ONLY || sampling_rate > 16000)
|
|
||||||
skip += 18;*/
|
|
||||||
|
|
||||||
switch(bandwidth)
|
switch(bandwidth)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue