summaryrefslogtreecommitdiff
path: root/src/opus_encoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/opus_encoder.c')
-rw-r--r--src/opus_encoder.c70
1 files changed, 49 insertions, 21 deletions
diff --git a/src/opus_encoder.c b/src/opus_encoder.c
index e8888959..4b6995d1 100644
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -294,7 +294,7 @@ static unsigned char gen_toc(int mode, int framerate, int bandwidth, int channel
}
#ifndef FIXED_POINT
-void silk_biquad_float(
+static void silk_biquad_float(
const opus_val16 *in, /* I: Input signal */
const opus_int32 *B_Q28, /* I: MA coefficients [3] */
const opus_int32 *A_Q28, /* I: AR coefficients [2] */
@@ -310,11 +310,11 @@ void silk_biquad_float(
opus_val32 inval;
opus_val32 A[2], B[3];
- A[0] = (opus_val32)(A_Q28[0] * (1./((opus_int32)1<<28)));
- A[1] = (opus_val32)(A_Q28[1] * (1./((opus_int32)1<<28)));
- B[0] = (opus_val32)(B_Q28[0] * (1./((opus_int32)1<<28)));
- B[1] = (opus_val32)(B_Q28[1] * (1./((opus_int32)1<<28)));
- B[2] = (opus_val32)(B_Q28[2] * (1./((opus_int32)1<<28)));
+ A[0] = (opus_val32)(A_Q28[0] * (1.f/((opus_int32)1<<28)));
+ A[1] = (opus_val32)(A_Q28[1] * (1.f/((opus_int32)1<<28)));
+ B[0] = (opus_val32)(B_Q28[0] * (1.f/((opus_int32)1<<28)));
+ B[1] = (opus_val32)(B_Q28[1] * (1.f/((opus_int32)1<<28)));
+ B[2] = (opus_val32)(B_Q28[2] * (1.f/((opus_int32)1<<28)));
/* Negate A_Q28 values and split in two parts */
@@ -511,20 +511,20 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
int prefill=0;
int start_band = 0;
int redundancy = 0;
- int redundancy_bytes = 0;
+ int redundancy_bytes = 0; /* Number of bytes to use for redundancy frame */
int celt_to_silk = 0;
VARDECL(opus_val16, pcm_buf);
int nb_compr_bytes;
int to_celt = 0;
opus_uint32 redundant_rng = 0;
int cutoff_Hz, hp_freq_smth1;
- int voice_est;
+ int voice_est; /* Probability of voice in Q7 */
opus_int32 equiv_rate;
int delay_compensation;
int frame_rate;
- opus_int32 max_rate;
+ opus_int32 max_rate; /* Max bitrate we're allowed to use */
int curr_bandwidth;
- opus_int32 max_data_bytes;
+ opus_int32 max_data_bytes; /* Max number of bytes we're allowed to use */
int extra_buffer, total_buffer;
int perform_analysis=0;
#ifndef FIXED_POINT
@@ -571,16 +571,22 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
if (max_data_bytes<3 || st->bitrate_bps < 3*frame_rate*8
|| (frame_rate<50 && (max_data_bytes*frame_rate<300 || st->bitrate_bps < 2400)))
{
+ /*If the space is too low to do something useful, emit 'PLC' frames.*/
int tocmode = st->mode;
+ int bw = st->bandwidth == 0 ? OPUS_BANDWIDTH_NARROWBAND : st->bandwidth;
if (tocmode==0)
tocmode = MODE_SILK_ONLY;
if (frame_rate>100)
tocmode = MODE_CELT_ONLY;
if (frame_rate < 50)
tocmode = MODE_SILK_ONLY;
- data[0] = gen_toc(tocmode, frame_rate,
- st->bandwidth == 0 ? OPUS_BANDWIDTH_NARROWBAND : st->bandwidth,
- st->stream_channels);
+ if(tocmode==MODE_SILK_ONLY&&bw>OPUS_BANDWIDTH_WIDEBAND)
+ bw=OPUS_BANDWIDTH_WIDEBAND;
+ else if (tocmode==MODE_CELT_ONLY&&bw==OPUS_BANDWIDTH_MEDIUMBAND)
+ bw=OPUS_BANDWIDTH_NARROWBAND;
+ else if (bw<=OPUS_BANDWIDTH_SUPERWIDEBAND)
+ bw=OPUS_BANDWIDTH_SUPERWIDEBAND;
+ data[0] = gen_toc(tocmode, frame_rate, bw, st->stream_channels);
RESTORE_STACK;
return 1;
}
@@ -713,6 +719,7 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
}
}
}
+ /* For the first frame at a new SILK bandwidth */
if (st->silk_bw_switch)
{
redundancy = 1;
@@ -720,6 +727,15 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
st->silk_bw_switch = 0;
}
+ if (redundancy)
+ {
+ /* Fair share of the max size allowed */
+ redundancy_bytes = IMIN(257, max_data_bytes*(opus_int32)(st->Fs/200)/(frame_size+st->Fs/200));
+ /* For VBR, target the actual bitrate (subject to the limit above) */
+ if (st->use_vbr)
+ redundancy_bytes = IMIN(redundancy_bytes, st->bitrate_bps/1600);
+ }
+
if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
{
silk_EncControlStruct dummy;
@@ -884,7 +900,7 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
st->mode = MODE_SILK_ONLY;
/* printf("%d %d %d %d\n", st->bitrate_bps, st->stream_channels, st->mode, curr_bandwidth); */
- bytes_target = IMIN(max_data_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1;
+ bytes_target = IMIN(max_data_bytes-redundancy_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1;
data += 1;
@@ -1004,7 +1020,7 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
st->silk_mode.useCBR = !st->use_vbr;
/* Call SILK encoder for the low band */
- nBytes = IMIN(1275, max_data_bytes-1);
+ nBytes = IMIN(1275, max_data_bytes-1-redundancy_bytes);
st->silk_mode.maxBits = nBytes*8;
/* Only allow up to 90% of the bits for hybrid mode*/
@@ -1016,8 +1032,6 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
/* Reduce the initial target to make it easier to reach the CBR rate */
st->silk_mode.bitRate = IMAX(1, st->silk_mode.bitRate-2000);
}
- if (redundancy)
- st->silk_mode.maxBits -= st->silk_mode.maxBits/(1 + frame_size/(st->Fs/200));
if (prefill)
{
@@ -1065,6 +1079,7 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
}
st->silk_mode.opusCanSwitch = st->silk_mode.switchReady;
+ /* FIXME: How do we allocate the redundancy for CBR? */
if (st->silk_mode.opusCanSwitch)
{
redundancy = 1;
@@ -1122,7 +1137,7 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
celt_encoder_ctl(celt_enc, OPUS_SET_VBR(1));
celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(st->vbr_constraint));
celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps));
- nb_compr_bytes = max_data_bytes-1;
+ nb_compr_bytes = max_data_bytes-1-redundancy_bytes;
} else {
nb_compr_bytes = bytes_target;
}
@@ -1160,8 +1175,8 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
g1 = g1==16384 ? Q15ONE : SHL16(g1,1);
g2 = g2==16384 ? Q15ONE : SHL16(g2,1);
#else
- g1 *= (1./16384);
- g2 *= (1./16384);
+ g1 *= (1.f/16384);
+ g2 *= (1.f/16384);
#endif
stereo_fade(pcm_buf+extra_buffer*st->channels, pcm_buf+extra_buffer*st->channels, g1, g2, celt_mode->overlap,
frame_size, st->channels, celt_mode->window, st->Fs);
@@ -1194,8 +1209,10 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
}
if (!redundancy)
+ {
st->silk_bw_switch = 0;
-
+ redundancy_bytes = 0;
+ }
if (st->mode != MODE_CELT_ONLY)start_band=17;
if (st->mode == MODE_SILK_ONLY)
@@ -1610,6 +1627,17 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
*value += st->delay_compensation;
}
break;
+ case OPUS_GET_SAMPLE_RATE_REQUEST:
+ {
+ opus_int32 *value = va_arg(ap, opus_int32*);
+ if (value==NULL)
+ {
+ ret = OPUS_BAD_ARG;
+ break;
+ }
+ *value = st->Fs;
+ }
+ break;
case OPUS_GET_FINAL_RANGE_REQUEST:
{
opus_uint32 *value = va_arg(ap, opus_uint32*);