Skip to content

Commit

Permalink
Add OPUS_SET_MIN_BANDWIDTH to set minInternalSampleRate for Silk mode…
Browse files Browse the repository at this point in the history
… (which is using NARROWBAND)

- Implement OPUS_SET_MIN_BANDWIDTH to OPUS_BANDWIDTH_WIDEBAND to allow configuration of minInternalSampleRate in Silk mode during encoding.
- This enables additional options for decoding, supporting both LACE and NOLACE modes, which require Wideband audio.
  • Loading branch information
tiennd3 authored and nguditi committed Oct 25, 2024
1 parent 7db2693 commit 60b45c0
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 1 deletion.
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

0 comments on commit 60b45c0

Please sign in to comment.