diff options
author | Jean-Marc Valin <jmvalin@amazon.com> | 2023-05-30 01:10:56 +0300 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@amazon.com> | 2023-06-16 20:02:19 +0300 |
commit | 9c137d493370cb195f0fb062f94b362c8bed481e (patch) | |
tree | ddbabc06b9d42cae27f186a786d386f5ca1d9948 /silk | |
parent | 4fbf6dcaf46bbc13ddd91a5762a486981fd0a14a (diff) |
Add offset and quantization to DRED bitstream
Brings the DRED implementation in line with the -00 draft
Diffstat (limited to 'silk')
-rw-r--r-- | silk/dred_coding.c | 10 | ||||
-rw-r--r-- | silk/dred_coding.h | 2 | ||||
-rw-r--r-- | silk/dred_config.h | 2 | ||||
-rw-r--r-- | silk/dred_decoder.c | 9 | ||||
-rw-r--r-- | silk/dred_decoder.h | 1 | ||||
-rw-r--r-- | silk/dred_encoder.c | 11 |
6 files changed, 32 insertions, 3 deletions
diff --git a/silk/dred_coding.c b/silk/dred_coding.c index ff592e81..34829390 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 a36f93d9..662ba549 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 f396219f..ff9903ba 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 20eb98ec..dea53251 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 e2640964..c7355ed1 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 ffc24b7c..02f1eb9f 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( |