diff options
Diffstat (limited to 'src/opus_encoder.c')
-rw-r--r-- | src/opus_encoder.c | 70 |
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*); |