summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@jmvalin.ca>2015-12-24 13:03:28 -0500
committerJean-Marc Valin <jmvalin@jmvalin.ca>2016-03-25 18:08:24 -0400
commit1fd6d47fac3eb5e29fbd44853d884f7ce6f50b2d (patch)
tree40adc36ae538d988d826c0b8708731ba810798d8
parentb4f7c2159fd9046f55001310d587a4b857183f98 (diff)
downloadopus-1fd6d47fac3eb5e29fbd44853d884f7ce6f50b2d.tar.gz
Quality: Adds SILK rate interpolation function
-rw-r--r--src/opus_encoder.c57
1 files changed, 45 insertions, 12 deletions
diff --git a/src/opus_encoder.c b/src/opus_encoder.c
index 9dfe6b02..c442bde5 100644
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -935,6 +935,49 @@ opus_val16 compute_stereo_width(const opus_val16 *pcm, int frame_size, opus_int3
return EXTRACT16(MIN32(Q15ONE, MULT16_16(20, mem->max_follower)));
}
+static int compute_silk_rate_for_hybrid(int rate, int bandwidth, int frame20ms, int vbr) {
+ int entry;
+ int i;
+ int N;
+ int silk_rate;
+ static int rate_table[][5] = {
+ /* |total| |-------- SILK------------|
+ SWB-10 FB-10 SWB-20 FB-20 */
+ { 0, 0, 0, 0, 0},
+ {12000, 10000, 10000, 10000, 10000},
+ {16000, 14000, 14000, 14000, 14000},
+ {20000, 16000, 16000, 16000, 16000},
+ {24000, 18000, 18000, 18000, 18000},
+ {32000, 22000, 22000, 22000, 22000},
+ {64000, 38000, 38000, 38000, 38000}
+ };
+ entry = 1 + 2*frame20ms + (bandwidth==OPUS_BANDWIDTH_FULLBAND);
+ N = sizeof(rate_table)/sizeof(rate_table[0]);
+ for (i=1;i<N;i++)
+ {
+ if (rate_table[i][0] > rate) break;
+ }
+ if (i == N)
+ {
+ silk_rate = rate_table[i-1][entry];
+ /* For now, just give 50% of the extra bits to SILK. */
+ silk_rate += (rate-rate_table[i-1][0])/2;
+ } else {
+ opus_int32 lo, hi, x0, x1;
+ lo = rate_table[i-1][entry];
+ hi = rate_table[i][entry];
+ x0 = rate_table[i-1][0];
+ x1 = rate_table[i][0];
+ silk_rate = (lo*(x1-rate) + hi*(rate-x0))/(x1-x0);
+ }
+ if (!vbr)
+ {
+ if (silk_rate > 8000)
+ silk_rate -= 1000;
+ }
+ return silk_rate;
+}
+
opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
unsigned char *data, opus_int32 out_data_bytes, int lsb_depth,
const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2,
@@ -1495,18 +1538,8 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
if( st->mode == MODE_HYBRID ) {
int HB_gain_ref;
/* Base rate for SILK */
- st->silk_mode.bitRate = st->stream_channels * ( 5000 + 1000 * ( st->Fs == 100 * frame_size ) );
- if( curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND ) {
- /* SILK gets 2/3 of the remaining bits */
- st->silk_mode.bitRate += ( total_bitRate - st->silk_mode.bitRate ) * 2 / 3;
- } else { /* FULLBAND */
- /* SILK gets 3/5 of the remaining bits */
- st->silk_mode.bitRate += ( total_bitRate - st->silk_mode.bitRate ) * 3 / 5;
- }
- /* Don't let SILK use more than 80% */
- if( st->silk_mode.bitRate > total_bitRate * 4/5 ) {
- st->silk_mode.bitRate = total_bitRate * 4/5;
- }
+ st->silk_mode.bitRate = compute_silk_rate_for_hybrid(total_bitRate,
+ curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr);
if (!st->energy_masking)
{
/* Increasingly attenuate high band when it gets allocated fewer bits */