diff --git a/silk/dred_coding.c b/silk/dred_coding.c index ff592e81725531aa8d2e07d628a6a53730473db5..34829390b8bb053c691ea30f050778796e059d94 100644 --- a/silk/dred_coding.c +++ b/silk/dred_coding.c @@ -37,11 +37,21 @@ #include "celt/cwrs.h" #include "celt/laplace.h" #include "os_support.h" +#include "dred_config.h" #define LATENT_DIM 80 #define PVQ_DIM 24 #define PVQ_K 82 +int compute_quantizer(int q0, int dQ, int i) { + int quant; + static const int dQ_table[8] = {0, 2, 3, 4, 6, 8, 12, 16}; + quant = 0; + quant = q0 + (dQ_table[dQ]*i + 8)/16; + return quant > 15 ? 15 : quant; + return (int) floor(0.5f + DRED_ENC_Q0 + 1.f * (DRED_ENC_Q1 - DRED_ENC_Q0) * i / (DRED_NUM_REDUNDANCY_FRAMES - 2)); +} + static void encode_pvq(const int *iy, int N, int K, ec_enc *enc) { int fits; celt_assert(N==24 || N==12 || N==6); diff --git a/silk/dred_coding.h b/silk/dred_coding.h index a36f93d92da67eb8c5dd4cc703c79466535c95e5..662ba549d92f14a5180c711af882670a2b5e0f71 100644 --- a/silk/dred_coding.h +++ b/silk/dred_coding.h @@ -31,6 +31,8 @@ #include "opus_types.h" #include "entcode.h" +int compute_quantizer(int q0, int dQ, int i); + void dred_encode_state(ec_enc *enc, float *x); void dred_encode_latents(ec_enc *enc, const float *x, const opus_uint16 *scale, const opus_uint16 *dzone, const opus_uint16 *r, const opus_uint16 *p0); diff --git a/silk/dred_config.h b/silk/dred_config.h index f396219f3c2932567a8219f5d578da4d0b9f622f..ff9903bafe9b8177e65b638aa70e4a8f4767600b 100644 --- a/silk/dred_config.h +++ b/silk/dred_config.h @@ -28,7 +28,7 @@ #ifndef DRED_CONFIG_H #define DRED_CONFIG_H -#define DRED_VERSION 0 +#define DRED_VERSION 1 #define DRED_MIN_BYTES 16 /* these are inpart duplicates to the values defined in dred_rdovae_constants.h */ diff --git a/silk/dred_decoder.c b/silk/dred_decoder.c index 20eb98ec46225394ae6d67fb3405e9766ff59cb3..dea532518ffab2994a0d6a7be9843809b641d6cb 100644 --- a/silk/dred_decoder.c +++ b/silk/dred_decoder.c @@ -48,6 +48,8 @@ int dred_ec_decode(OpusDRED *dec, const opus_uint8 *bytes, int num_bytes, int mi int q_level; int i; int offset; + int q0; + int dQ; /* since features are decoded in quadruples, it makes no sense to go with an uneven number of redundancy frames */ @@ -55,6 +57,11 @@ int dred_ec_decode(OpusDRED *dec, const opus_uint8 *bytes, int num_bytes, int mi /* decode initial state and initialize RDOVAE decoder */ ec_dec_init(&ec, (unsigned char*)bytes, num_bytes); + dec->dred_offset = ec_dec_uint(&ec, 32); + q0 = ec_dec_uint(&ec, 16); + dQ = ec_dec_uint(&ec, 8); + /*printf("%d %d %d\n", dred_offset, q0, dQ);*/ + dred_decode_state(&ec, dec->state); /* decode newest to oldest and store oldest to newest */ @@ -63,7 +70,7 @@ int dred_ec_decode(OpusDRED *dec, const opus_uint8 *bytes, int num_bytes, int mi /* FIXME: Figure out how to avoid missing a last frame that would take up < 8 bits. */ if (8*num_bytes - ec_tell(&ec) <= 7) break; - q_level = (int) floor(.5 + DRED_ENC_Q0 + 1.f * (DRED_ENC_Q1 - DRED_ENC_Q0) * i / (DRED_NUM_REDUNDANCY_FRAMES - 2)); + q_level = compute_quantizer(q0, dQ, i/2); offset = q_level * DRED_LATENT_DIM; dred_decode_latents( &ec, diff --git a/silk/dred_decoder.h b/silk/dred_decoder.h index e2640964704686bc3743f53e6c7a8c074129f9e1..c7355ed109caf6c2e3868eb5fd3df0f10ac4d338 100644 --- a/silk/dred_decoder.h +++ b/silk/dred_decoder.h @@ -39,6 +39,7 @@ struct OpusDRED { float latents[(DRED_NUM_REDUNDANCY_FRAMES/2)*DRED_LATENT_DIM]; int nb_latents; int process_stage; + int dred_offset; }; diff --git a/silk/dred_encoder.c b/silk/dred_encoder.c index ffc24b7c80349d9a6959a37ee1ec01741d4fe527..02f1eb9fbbf06be3755ffe713c88d45f175ec805 100644 --- a/silk/dred_encoder.c +++ b/silk/dred_encoder.c @@ -85,9 +85,18 @@ int dred_encode_silk_frame(DREDEnc *enc, unsigned char *buf, int max_chunks, int int i; int offset; int ec_buffer_fill; + int dred_offset; + int q0; + int dQ; /* entropy coding of state and latents */ ec_enc_init(&ec_encoder, buf, max_bytes); + dred_offset = 8; /* 20 ms */ + q0 = DRED_ENC_Q0; + dQ = 3; + ec_enc_uint(&ec_encoder, dred_offset, 32); + ec_enc_uint(&ec_encoder, q0, 16); + ec_enc_uint(&ec_encoder, dQ, 8); dred_encode_state(&ec_encoder, enc->state_buffer); for (i = 0; i < IMIN(2*max_chunks, enc->latents_buffer_fill-1); i += 2) @@ -95,7 +104,7 @@ int dred_encode_silk_frame(DREDEnc *enc, unsigned char *buf, int max_chunks, int ec_enc ec_bak; ec_bak = ec_encoder; - q_level = (int) floor(0.5f + DRED_ENC_Q0 + 1.f * (DRED_ENC_Q1 - DRED_ENC_Q0) * i / (DRED_NUM_REDUNDANCY_FRAMES - 2)); + q_level = compute_quantizer(q0, dQ, i/2); offset = q_level * DRED_LATENT_DIM; dred_encode_latents(