diff --git a/silk/dred_coding.c b/silk/dred_coding.c index 01792e0ae3ee2f85d22aec277d400d48a4b093f7..66360454c40252d4c6633a11e95f2dcc19576b67 100644 --- a/silk/dred_coding.c +++ b/silk/dred_coding.c @@ -30,17 +30,11 @@ #endif #include <math.h> -#include <stdio.h> #include "celt/entenc.h" -#include "celt/laplace.h" #include "os_support.h" #include "dred_config.h" #include "dred_coding.h" -#include "vec.h" - -#define LATENT_DIM 80 -#define STATE_DIM 80 int compute_quantizer(int q0, int dQ, int i) { int quant; @@ -50,94 +44,3 @@ int compute_quantizer(int q0, int dQ, int i) { 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)); } - -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) { - int i; - float eps = .1f; - for (i=0;i<LATENT_DIM;i++) { - float delta; - float xq; - int q; - delta = dzone[i]*(1.f/1024.f); - xq = x[i]*scale[i]*(1.f/256.f); - xq = xq - delta*tanh_approx(xq/(delta+eps)); - q = (int)floor(.5f+xq); - /* Make the impossible actually impossible. */ - if (r[i] == 0 || p0[i] >= 32767) q = 0; - ec_laplace_encode_p0(enc, q, p0[i], r[i]); - } -} - -void dred_decode_latents(ec_dec *dec, float *x, const opus_uint16 *scale, const opus_uint16 *r, const opus_uint16 *p0) { - int i; - for (i=0;i<LATENT_DIM;i++) { - int q; - q = ec_laplace_decode_p0(dec, p0[i], r[i]); - x[i] = q*256.f/(scale[i] == 0 ? 1 : scale[i]); - } -} - -#if 0 -#include <stdlib.h> - -#define DATA_SIZE 10000 - -int main() -{ - ec_enc enc; - ec_dec dec; - int iter; - int bytes; - opus_int16 scale[LATENT_DIM]; - opus_int16 dzone[LATENT_DIM]; - opus_int16 r[LATENT_DIM]; - opus_int16 p0[LATENT_DIM]; - unsigned char *ptr; - int k; - - for (k=0;k<LATENT_DIM;k++) { - scale[k] = 256; - dzone[k] = 0; - r[k] = 12054; - p0[k] = 12893; - } - ptr = (unsigned char *)malloc(DATA_SIZE); - ec_enc_init(&enc,ptr,DATA_SIZE); - for (iter=0;iter<1;iter++) { - float x[PVQ_DIM]; - float sum=1e-30; - for (k=0;k<PVQ_DIM;k++) { - x[k] = log(1e-15+(float)rand()/RAND_MAX)-log(1e-15+(float)rand()/RAND_MAX); - sum += fabs(x[k]); - } - for (k=0;k<PVQ_DIM;k++) x[k] *= (1.f/sum); - /*for (k=0;k<PVQ_DIM;k++) printf("%f ", x[k]); - printf("\n");*/ - dred_encode_state(&enc, x); - } - for (iter=0;iter<1;iter++) { - float x[LATENT_DIM]; - for (k=0;k<LATENT_DIM;k++) { - x[k] = log(1e-15+(float)rand()/RAND_MAX)-log(1e-15+(float)rand()/RAND_MAX); - } - for (k=0;k<LATENT_DIM;k++) printf("%f ", x[k]); - printf("\n"); - dred_encode_latents(&enc, x, scale, dzone, r, p0); - } - bytes = (ec_tell(&enc)+7)/8; - ec_enc_shrink(&enc, bytes); - ec_enc_done(&enc); - - ec_dec_init(&dec,ec_get_buffer(&enc),bytes); - for (iter=0;iter<1;iter++) { - float x[PVQ_DIM]; - dred_decode_state(&dec, x); - } - for (iter=0;iter<1;iter++) { - float x[LATENT_DIM]; - dred_decode_latents(&dec, x, scale, r, p0); - for (k=0;k<LATENT_DIM;k++) printf("%f ", x[k]); - printf("\n"); - } -} -#endif diff --git a/silk/dred_coding.h b/silk/dred_coding.h index 0cefde7fb7adecc062e1610174e7fc5fd5a86441..0a5ddb61fb51c914fa2045633021c6be42b49509 100644 --- a/silk/dred_coding.h +++ b/silk/dred_coding.h @@ -33,12 +33,4 @@ int compute_quantizer(int q0, int dQ, int i); -void dred_encode_state(ec_enc *enc, const 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); - -void dred_decode_state(ec_enc *dec, float *x); - -void dred_decode_latents(ec_dec *dec, float *x, const opus_uint16 *scale, const opus_uint16 *r, const opus_uint16 *p0); - #endif diff --git a/silk/dred_decoder.c b/silk/dred_decoder.c index acc79ec3a492b5c6dd34343b5db3634f1b041b81..658d340fb80ac28aa673b44cef68a3d90a663ae5 100644 --- a/silk/dred_decoder.c +++ b/silk/dred_decoder.c @@ -35,6 +35,7 @@ #include "dred_decoder.h" #include "dred_coding.h" #include "celt/entdec.h" +#include "celt/laplace.h" /* From http://graphics.stanford.edu/~seander/bithacks.html#FixedSignExtend */ static int sign_extend(int x, int b) { @@ -42,6 +43,14 @@ static int sign_extend(int x, int b) { return (x ^ m) - m; } +static void dred_decode_latents(ec_dec *dec, float *x, const opus_uint16 *scale, const opus_uint16 *r, const opus_uint16 *p0, int dim) { + int i; + for (i=0;i<dim;i++) { + int q; + q = ec_laplace_decode_p0(dec, p0[i], r[i]); + x[i] = q*256.f/(scale[i] == 0 ? 1 : scale[i]); + } +} int dred_ec_decode(OpusDRED *dec, const opus_uint8 *bytes, int num_bytes, int min_feature_frames) { @@ -74,7 +83,8 @@ int dred_ec_decode(OpusDRED *dec, const opus_uint8 *bytes, int num_bytes, int mi dec->state, quant_scales + state_qoffset, r + state_qoffset, - p0 + state_qoffset); + p0 + state_qoffset, + DRED_STATE_DIM); /* decode newest to oldest and store oldest to newest */ for (i = 0; i < IMIN(DRED_NUM_REDUNDANCY_FRAMES, (min_feature_frames+1)/2); i += 2) @@ -89,7 +99,8 @@ int dred_ec_decode(OpusDRED *dec, const opus_uint8 *bytes, int num_bytes, int mi &dec->latents[(i/2)*DRED_LATENT_DIM], quant_scales + offset, r + offset, - p0 + offset + p0 + offset, + DRED_LATENT_DIM ); offset = 2 * i * DRED_NUM_FEATURES; diff --git a/silk/dred_encoder.c b/silk/dred_encoder.c index 3df420be2d8f89dd4ec083284c382aca9963acbc..1edfb3168b2693887a4e1839784390178921c7b1 100644 --- a/silk/dred_encoder.c +++ b/silk/dred_encoder.c @@ -43,6 +43,9 @@ #include "dred_decoder.h" #include "float_cast.h" #include "os_support.h" +#include "vec.h" +#include "celt/laplace.h" + int dred_encoder_load_model(DREDEnc* enc, const unsigned char *data, int len) { @@ -208,6 +211,23 @@ void dred_compute_latents(DREDEnc *enc, const float *pcm, int frame_size, int ex } } +static 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, int dim) { + int i; + float eps = .1f; + for (i=0;i<dim;i++) { + float delta; + float xq; + int q; + delta = dzone[i]*(1.f/1024.f); + xq = x[i]*scale[i]*(1.f/256.f); + xq = xq - delta*tanh_approx(xq/(delta+eps)); + q = (int)floor(.5f+xq); + /* Make the impossible actually impossible. */ + if (r[i] == 0 || p0[i] >= 32767) q = 0; + ec_laplace_encode_p0(enc, q, p0[i], r[i]); + } +} + int dred_encode_silk_frame(const DREDEnc *enc, unsigned char *buf, int max_chunks, int max_bytes) { const opus_uint16 *dead_zone = DRED_rdovae_get_dead_zone_pointer(); const opus_uint16 *p0 = DRED_rdovae_get_p0_pointer(); @@ -237,7 +257,8 @@ int dred_encode_silk_frame(const DREDEnc *enc, unsigned char *buf, int max_chunk quant_scales + state_qoffset, dead_zone + state_qoffset, r + state_qoffset, - p0 + state_qoffset); + p0 + state_qoffset, + DRED_STATE_DIM); if (ec_tell(&ec_encoder) > 8*max_bytes) { return 0; } @@ -255,7 +276,8 @@ int dred_encode_silk_frame(const DREDEnc *enc, unsigned char *buf, int max_chunk quant_scales + offset, dead_zone + offset, r + offset, - p0 + offset + p0 + offset, + DRED_LATENT_DIM ); if (ec_tell(&ec_encoder) > 8*max_bytes) { ec_encoder = ec_bak;