Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OPUS_SET_MIN_BANDWIDTH to set minInternalSampleRate #373

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions include/opus_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ extern "C" {
#define OPUS_GET_BITRATE_REQUEST 4003
#define OPUS_SET_MAX_BANDWIDTH_REQUEST 4004
#define OPUS_GET_MAX_BANDWIDTH_REQUEST 4005
#define OPUS_SET_MIN_BANDWIDTH_REQUEST 40050
#define OPUS_GET_MIN_BANDWIDTH_REQUEST 40051
#define OPUS_SET_VBR_REQUEST 4006
#define OPUS_GET_VBR_REQUEST 4007
#define OPUS_SET_BANDWIDTH_REQUEST 4008
Expand Down Expand Up @@ -406,6 +408,29 @@ extern "C" {
* @hideinitializer */
#define OPUS_GET_MAX_BANDWIDTH(x) OPUS_GET_MAX_BANDWIDTH_REQUEST, __opus_check_int_ptr(x)

/** Configures the minimum bandpass that the encoder will select automatically.
* LACE and NoLACE are currently only applied when the frame size is 20 ms (the default)
* and the bandwidth is at least wideband, to use LACE and NOLACE for low bandwidth
* and keep OPUS_AUTO for other bandwidth, we may need OPUS_SET_MIN_BANDWIDTH
* @see OPUS_GET_MIN_BANDWIDTH
* @param[in] x <tt>opus_int32</tt>: Allowed values:
* <dl>
* <dt>OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
* <dt>OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_MIN_BANDWIDTH(x) OPUS_SET_MIN_BANDWIDTH_REQUEST, __opus_check_int(x)

/** Gets the encoder's configured minimum allowed bandpass.
* @see OPUS_SET_MIN_BANDWIDTH
* @param[out] x <tt>opus_int32 *</tt>: Allowed values:
* <dl>
* <dt>#OPUS_BANDWIDTH_NARROWBAND</dt> <dd>4 kHz passband</dd>
* <dt>#OPUS_BANDWIDTH_WIDEBAND</dt> <dd>8 kHz passband</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_MIN_BANDWIDTH(x) OPUS_GET_MIN_BANDWIDTH_REQUEST, __opus_check_int_ptr(x)

/** Sets the encoder's bandpass to a specific value.
* This prevents the encoder from automatically selecting the bandpass based
* on the available bitrate. If an application knows the bandpass of the input
Expand Down
40 changes: 39 additions & 1 deletion src/opus_encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ struct OpusEncoder {
int signal_type;
int user_bandwidth;
int max_bandwidth;
int min_bandwidth;
int user_forced_mode;
int voice_ratio;
opus_int32 Fs;
Expand Down Expand Up @@ -270,6 +271,7 @@ int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int applicat
st->signal_type = OPUS_AUTO;
st->user_bandwidth = OPUS_AUTO;
st->max_bandwidth = OPUS_BANDWIDTH_FULLBAND;
st->min_bandwidth = OPUS_BANDWIDTH_NARROWBAND;
st->force_channels = OPUS_AUTO;
st->user_forced_mode = OPUS_AUTO;
st->voice_ratio = -1;
Expand Down Expand Up @@ -1476,6 +1478,9 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
mode transitions. */
if (bandwidth == OPUS_BANDWIDTH_MEDIUMBAND)
bandwidth = OPUS_BANDWIDTH_WIDEBAND;
/* If have minbandwidth (currently just use wideband to apply LACE & NOLACE)*/
if(st->min_bandwidth == OPUS_BANDWIDTH_WIDEBAND && bandwidth < st->min_bandwidth)
bandwidth = st->min_bandwidth;
st->bandwidth = st->auto_bandwidth = bandwidth;
/* Prevents any transition to SWB/FB until the SILK layer has fully
switched to WB mode and turned the variable LP filter off */
Expand Down Expand Up @@ -1948,7 +1953,13 @@ static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_val16 *pc
/* Don't allow bandwidth reduction at lowest bitrates in hybrid mode */
st->silk_mode.minInternalSampleRate = 16000;
} else {
st->silk_mode.minInternalSampleRate = 8000;
if (st->min_bandwidth == OPUS_BANDWIDTH_WIDEBAND) {
st->silk_mode.minInternalSampleRate = 16000;
}
else {
st->silk_mode.minInternalSampleRate = 8000;
}

}

st->silk_mode.maxInternalSampleRate = 16000;
Expand Down Expand Up @@ -2641,6 +2652,33 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
*value = st->max_bandwidth;
}
break;
case OPUS_SET_MIN_BANDWIDTH_REQUEST:
{
opus_int32 value = va_arg(ap, opus_int32);
if (value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND)
{
goto bad_arg;
}
if (value == OPUS_BANDWIDTH_WIDEBAND) {
st->min_bandwidth = OPUS_BANDWIDTH_WIDEBAND;
st->silk_mode.minInternalSampleRate = 16000;
}
else {
st->min_bandwidth = OPUS_BANDWIDTH_NARROWBAND;
st->silk_mode.minInternalSampleRate = 8000;
}
}
break;
case OPUS_GET_MIN_BANDWIDTH_REQUEST:
{
opus_int32* value = va_arg(ap, opus_int32*);
if (!value)
{
goto bad_arg;
}
*value = st->min_bandwidth;
}
break;
case OPUS_SET_BANDWIDTH_REQUEST:
{
opus_int32 value = va_arg(ap, opus_int32);
Expand Down